Metodi getter / setter indipendenti o combinati?

Mentre lavoravo a un progetto, ho apportto alcune modifiche e ho esplorato i documenti esistenti dell'API framework per get informazioni dettagliate.

Durante la lettura dei documenti Kohana, ho notato che i getter / setter di una determinata class sono in genere combinati:

public function someProperty($value = null){ if(is_null($value){ return $this->_someProperty; } $this->_someProperty = $value; return $this; } 

Piuttosto che:

 public function setSomeProperty($value){ $this->_someProperty = $value; return $this; } public function getSomeProperty(){ return $this->_someProperty; } 

C'è qualche valore nel fare questo ( il primo ), oltre a diminuire il count dei methods di una data class? Ho sempre capito che i methods ( funzioni in generale ) dovrebbero essere più descrittivi di un'azione. Altri sviluppatori esperti rabbrividiscono, anche solo un pochino, quando vedono questo?

Sono stato semplicemente sorpreso di vedere un framework popolare utilizzare tali convenzioni ( non ho usato Kohana ovviamente )

Considero questa ctriggers pratica perché viola CommandQuerySeparation . L'impostazione di un valore cambia stato (command). Ottenere un valore richiede lo stato (Query). Un metodo non dovrebbe fare entrambi, ma solo una cosa.

Inoltre, non è proprio ovvio come funzioni un metodo quando viene chiamato semplicemente username, ad esempio non ha un verbo, come get o set. Ciò diventa ancora peggiore nell'esempio, poiché il valore restituito è l'object stesso o il valore della properties;, quindi non è coerente.

Inoltre, i getter (e i setter) dovrebbero essere usati con parsimonia, in quanto convoluteranno rapidamente la tua API. Più getter e setter hai, più conoscenza di un object è richiesta dai collaboratori di quell'object. Se trovi che i tuoi oggetti chiedono altri oggetti sui loro interni, è probabile che tu abbia sbagliato le responsabilità.

jQuery funziona allo stesso modo di Kohana. Comunque penso che sia meglio creare methods separati per impostare e get. È più ovvio quale sia il metodo e penso che sia più praticamente in codice-completamento nel tuo ide. Ad esempio, si digita set e si ottiene un elenco di tutte le properties; che è ansible impostare.

Un altro svantaggio è: cosa succede se si desidera impostare un valore veramente null ? Questo non functionrebbe dato che null è l'identificatore per il return nel valore, sei limitato nell'impostazione di valori specifici …

Quindi è bello, dal momento che dovrai scrivere less, ma quali sono tre lettere ( set / get ) di fronte ai tuoi methods?

Nonostante Kohana utilizzi una tecnica così insolita per l'OOP, penso che dovresti seguire le convenzioni di programmazione all'inizio. Ma ovviamente è meglio usare getter e setter separati per each properties; nelle tue classi. Quindi, se è ansible usarli non infrangere le convenzioni: fallo e non sbaglierai;). Puoi anche leggere qui le buone abitudini in PHP OOP – http://www.ibm.com/developerworks/opensource/library/os-php-7oohabits/ se hai dei dubbi sull'utilizzo di alcune tecniche OOP. Spero che ti aiuterà 🙂

Preferirei credere che avessero una spiegazione ragionevole per farlo in questo modo. Ad esempio, per semplificare l'implementazione di ArrayAccess. L'unico modo per sapere con certezza è di chiederli direttamente.

Per rispondere alla tua domanda, sì, rabbrividisco quando vedo il primo metodo. Va contro i principi OOP.

Perché non farlo in questo modo?

 public function someProperty($value = null) { if (func_num_args() === 1) { $this->someProperty = $value; return $this; } else { return $this->someProperty; } } 

Questo sarebbe l'unico modo corretto per implementare un getter / setter combinato

Se lo fai ovunque è un buon modo, ma in realtà deve essere per tutto , forse i programmatori di questo framework sono abituati a farlo, (è un po 'jquery allo stesso modo)

Comunque mi confonderebbe

Per impostare e get utilizzo sempre setter e getter :

  public function __set($key, $value) { // assign value $value to $this->key } public function __get($key) { // return value of this->key } 

Per amor di discussione,

L'approccio combinato offre alcuni vantaggi:

  1. Evita __get e __set magia mentre emula ancora una properties; pubblica. (Non consiglierei mai di usare la magia per queste situazioni comunque)
  2. L'uso di thing() è less getThing() setThing() rispetto all'utilizzo di getThing() setThing() .
  3. Anche se i methods faranno di più, possono ancora essere considerati come "fare una thing() ", cioè gestire la thing() . Le properties; fanno anche più di una cosa. Ti permettono di impostare e get valori.
  4. Si sostiene che la thing() non dia un verbo. Tuttavia, possiamo supporre che una thing() senza un verbo significhi che la usiamo come una properties; ( otteniamo e impostiamo ). Per le interfacce, possiamo dire che una thing() senza argomento è di sola lettura e una thing($arg) con un argomento è lettura / scrittura . Perché dovremmo essere timidi dall'adottarlo? Ad un certo punto abbiamo adottato l'idea di aggiungere getter e setter no?
  5. Se si utilizza un linguaggio basato sul Web (come PHP), è probabile che si stia utilizzando jQuery. JQuery sta già facendo questo genere di thing() e ha funzionato bene.
  6. L'uso di func_num_args() , come già detto, aiuta a raggiungere questo approccio perfettamente.

Personalmente, ho già preso una buona parte dei rischi nelle mie attuali app a questo punto, quindi probabilmente andrò con i vecchi getter e setter provati e veri ( vedi la sezione "Trovare il saldo" del post di Jimmy Bogard in riguarda i getter / setter per le operazioni sui dati ). E suppongo che siamo già addestrati a cercare questi prefissi get / set (così come i nostri IDE) per vedere quali properties; possiamo lavorare in una class. Questa è una discussione su cui sarei disposto a tornare ad un certo punto.