2012-05-16 8 views
12

Ho visto alcuni progetti in cui le classi stanno ottenendo e impostando i metodi per manipolare i dati di inserimento. Dammi un esempio qui:Vale la pena di fare i metodi get e set in 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); 
    } 
} 

è al di sopra della classe di esempio che ho visto. E sotto è il processo come lo stanno usando:

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

$studen->UpdateStudent(); 

Vale la pena farlo in questo modo? Personalmente ritengo sia inutile impostare il campo e quindi ottenere e aggiornare i record al suo interno. Ci vuole davvero molto tempo per farlo per ogni modulo. Qual è il modo migliore per gestire questa cosa? C'è qualche problema alla sicurezza in questo modo?

+1

I modificatori di accesso (come 'private') sono spesso interpretati erroneamente come funzionalità di sicurezza. Nella loro attuale incarnazione in C++, essi erano in realtà destinati a limitare l'esposizione ABI (non API); che non è poi così rilevante per PHP e linguaggi di scripting. Richiedere setter e getter è quindi spesso un effetto collaterale, ma non è molto orientato agli oggetti. Vedi anche [PHP Getters and setters: male o male necessario?] (Http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessitive-evil/) e [Java: Getter e setter sono evil] (http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html) – mario

+0

possibile duplicato di [È davvero sbagliato usare non setter e getter?] (http://stackoverflow.com/questions/808348/is-it-really-that-wrong-not-using-setters-and-getters) – mario

risposta

10

Vale la pena farlo in questo modo?

Dipende.

Astrarre un campo da parte dell'utente, esponendo una proprietà "intelligente" (vale a dire getter e/o setter) ha due svantaggi:

  1. È necessario scrivere codice più; se la proprietà non fa nulla di intelligente, questo è un codice che non fa nulla di utile.
  2. L'utente della proprietà è leggermente disturbato perché deve digitare un po 'di più.

E ha un vantaggio:

  1. In futuro è possibile aggiungere logica per le proprietà, anche se prima non c'era senza infrangere il codice dei vostri utenti.

Se questo vantaggio è significativo (ad esempio, si sta scrivendo una libreria software riutilizzabile), ha molto senso scrivere proprietà anziché campi nudi. Altrimenti, stai lavorando senza alcun beneficio.

Qual è il modo migliore per gestire cosa del genere?

È possibile ignorare le magiche __get e __set funzioni (forse in una classe base in modo da poter ereditare l'override pure) per l'inoltro automatico di proprietà accessi ai tuoi getter e setter. codice semplificato:

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); 
} 

Caveat emptor: Dal __get e __set vengono sovrascritte, __isset e __unset dovrebbe essere ignorato, come pure!

C'è qualche sicurezza interessata a farlo in questo modo?

No, nessuno (presumendo che non si inseriscano errori accidentalmente).

+0

Non penso che ci sarà alcuna logica futura in esso. Le persone della mia nuova società usano quello per la semplice esecuzione di una cosa del database. Pensano che sia sicuro. Non so come si sta proteggendo. –

+2

@SalmanKhimani: le persone sono molto cattive nel predire il futuro. Se è il codice della compagnia, vai per getter e setter e non guardare indietro. – Jon

1

Fare setter e getter aiuta a rafforzare l'incapsulamento OOP. Non sono sicuro per PHP, ma per molti altri linguaggi (Java, C++), un buon IDE (eclipse/netbeans) genererà automaticamente questi setter e getter per te.

Potrebbe non essere immediatamente evidente per i tipi semplici, ma se è necessario eseguire qualsiasi tipo di elaborazione più complessa, diventa più ovvio.

+0

Non migliorano l'incapsulamento OOP ma sono piuttosto una soluzione per la mancanza di * proprietà * in una lingua – ThiefMaster

+0

@ThiefMaster, penso che sia davvero d'aiuto se è necessario un qualche tipo di logica/elaborazione per memorizzare il valore. – Brady

+0

Sì, ma sono ancora una brutta soluzione. In Python è possibile utilizzare ad esempio public vars e semplicemente creare una * proprietà * (che accede alle funzioni getter/setter personalizzate) se è necessaria una logica aggiuntiva. In C# si creano proprietà e si lascia che il compilatore crei il "semplice" getter/setter per esso internamente (non le vedi mai e non sono funzioni effettive che puoi chiamare direttamente) e se hai mai bisogno di logica personalizzata, devi semplicemente implementarle per conto proprio. Tuttavia, l'accesso alla proprietà, indipendentemente dal fatto che vi siano getter/setter o meno, viene sempre eseguito tramite 'obj.prop' come una variabile – ThiefMaster

5

Nelle lingue che non hanno le proprietà (le "variabili" del membro pubblico che in realtà portano a chiamate di funzione) si consiglia di utilizzare getter/setters invece di variabili pubbliche. Altrimenti non è possibile aggiungere la logica (ad es. Quando si imposta una variabile) in un secondo momento se le persone stanno già utilizzando il campo normale.

Dal momento che PHP è un tale linguaggio (purtroppo) la risposta è sì, li usa.