2012-05-16 47 views
12

我已經看到了一些項目,其中類有get和set方法來操作插入數據。讓我舉一個例子:是否值得在OOP中獲取和設置方法?

class Student extends dbClass 
{ 
    private $TableID; 
    private $FullName; 
    private $Gender; 
    private $Address; 




    function setTableID($Value) 
    { 
     $this->TableID = $Value; 
    } 

    function getTableID() 
    { 
     return $this->TableID; 
    } 

    function setFullName($Value) 
    { 
     $this->FullName = $Value; 
    } 

    function getFullName() 
    { 
     return $this->FullName; 
    } 

    function setGender($Value) 
    { 
     $this->Gender = $Value; 
    } 

    function getGender() 
    { 
     return $this->Gender; 
    } 

    function setAddress($Value) 
    { 
     $this->Address = $Value; 
    } 

    function getAddress() 
    { 
     return $this->Address; 
    } 


    function UpdateStudent() 
    { 
     $sql = "UPDATE INTO usertable SET 
     FullName = '".$this->getFullName()."', 
     Gender = '".$this->getGender()."', 
     Address = '".$this->getAddress()."' 
     where TableID='".$this->getTableID()."'"; 
     $this->query($sql); 
    } 
} 

上面是我見過的示例類。下面是他們如何使用它的過程:

$student = new Student; 
$student->setTableID = 1; 
$student->setFullName('My Name'); 
$student->setGender('Male'); 
$student->setAddress('this is my address'); 

$studen->UpdateStudent(); 

是否值得這樣做?我個人認爲它無用設置字段,然後獲取並更新記錄。每個模塊都需要花費很多時間。處理這種事情的最佳方式是什麼? 有沒有關注這樣做的安全措施?

+1

訪問修飾符(如'private')經常被誤解爲安全功能。在他們目前的C++化身中,他們實際上是想限制ABI(而不是API)暴露;這與PHP和腳本語言確實無關。因此要求引導者和獲取者往往是一個副作用,但它不是很面向對象的。另見[PHP Getters and setters:evil or necessary evil?](http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessary-evil/)和[Java:Getters and setters是邪惡](http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html) – mario

+0

可能的重複[是否真的沒有使用setters和getters錯誤?](http:/ /stackoverflow.com/questions/808348/is-it-really-that-wrong-not-using-setters-and-getters) – mario

回答

10

是否值得這樣做?

這取決於。

通過暴露一個「智能」屬性(即,吸氣劑和/或setter)從用戶抽象的字段有兩個缺點:

  1. 你需要寫更多的代碼;如果財產並沒有真正做出任何聰明的事情,這是沒有用的代碼。
  2. 該屬性的用戶稍有不便,因爲他們必須輸入更多一點。

而且它有一個好處:

  1. 在未來你可以添加邏輯,即使有沒有之前不會破壞用戶的碼屬性。

如果這個優點是有意義的(例如,你正在編寫一個可重用的軟件庫),那麼編寫屬性而不是裸露的字段是很有意義的。如果沒有,你正在做的工作沒有任何好處。

處理這種事情的最佳方法是什麼?

可以覆蓋魔術__get__set功能(也許在一個基類,所以你可以繼承倍率爲好)自動轉發屬性訪問到你的getter和setter。簡化代碼:

public function __get($name) { 
    $getter = 'get'.$name; 
    if (method_exists($this, $getter)) { 
     return $this->$getter(); 
    } 

    $message = sprintf('Class "%1$s" does not have a property named "%2$s" or a method named "%3$s".', get_class($this), $name, $getter); 
    throw new \OutOfRangeException($message); 
} 

public function __set($name, $value) { 
    $setter = 'set'.$name; 
    if (method_exists($this, $setter)) { 
     return $this->$setter($value); 
    } 

    $getter = 'get'.$name; 
    if (method_exists($this, $getter)) { 
     $message = sprintf('Implicit property "%2$s" of class "%1$s" cannot be set because it is read-only.', get_class($this), $name); 
    } 
    else { 
     $message = sprintf('Class "%1$s" does not have a property named "%2$s" or a method named "%3$s".', get_class($this), $name, $setter); 
    } 
    throw new \OutOfRangeException($message); 
} 

買者自負:由於__get__set被覆蓋,__isset__unset應該重寫以及!

有沒有關心這樣做的安全嗎?

不,根本沒有(假設您不意外插入錯誤)。

+0

我不認爲會有任何未來的邏輯。我的新公司中的人員使用它來執行數據庫事務。他們認爲它是安全的。我不知道它是如何保護的。 –

+2

@SalmanKhimani:人們對未來的預測非常糟糕。如果是公司代碼,那就去獲得者和制定者,不要回頭。 – Jon

1

使setter和getters有助於強制執行OOP封裝。我不知道PHP,但對於許多其他語言(Java,C++),一個好的IDE(eclipse/netbeans)會自動爲你生成這些setters和getters。

簡單類型可能不會立即顯而易見,但是如果需要執行任何類型的更復雜的處理,那麼它就會變得更加明顯。

+0

他們並沒有真正改善OOP封裝,而是一種解決方案,因爲缺少*屬性*用語言。 – ThiefMaster

+0

@ThiefMaster,如果需要任何種類的邏輯/處理來存儲值,我認爲它確實有幫助。 – Brady

+0

是的,但他們仍然是一個討厭的解決方法。在python中,你可以使用公共變量,如果你需要額外的邏輯,只需創建一個*屬性*(它可以訪問自定義的getter/setter函數)。在C#中,您可以創建屬性並讓編譯器在內部爲它創建「簡單」getter/setter(您從不會看到它們,它們也不是可以直接調用的實際函數),並且如果您需要自定義邏輯,只需實現這些函數在你自己的。但是,訪問屬性 - 無論是否有getter/setters - 總是通過'obj.prop'完成,就像變量 – ThiefMaster

5

在沒有屬性的語言(公共成員「變量」實際上導致函數調用)通常建議使用getter/setters而不是公共變量。否則,如果人們已經在使用普通字段,則不能再添加邏輯(例如,設置變量時)。

由於PHP是這樣一種語言(不幸),答案是是的,使用它們