PHP
Modelli di progettazione
Ricerca…
introduzione
Questo argomento fornisce esempi di modelli di progettazione ben noti implementati in PHP.
Metodo di concatenamento in PHP
Il metodo Chaining è una tecnica spiegata nel libro Domain Specific Languages di Martin Fowler . Il concatenamento del metodo è riassunto come
Considera questa parte di codice non concatenante / regolare (trasferita su PHP dal libro sopra menzionato)
$hardDrive = new HardDrive;
$hardDrive->setCapacity(150);
$hardDrive->external();
$hardDrive->setSpeed(7200);
Il metodo Chaining consente di scrivere le dichiarazioni di cui sopra in modo più compatto:
$hardDrive = (new HardDrive)
->setCapacity(150)
->external()
->setSpeed(7200);
Tutto quello che devi fare per far funzionare tutto questo è return $this
nei metodi da cui vuoi concatenare:
class HardDrive {
protected $isExternal = false;
protected $capacity = 0;
protected $speed = 0;
public function external($isExternal = true) {
$this->isExternal = $isExternal;
return $this; // returns the current class instance to allow method chaining
}
public function setCapacity($capacity) {
$this->capacity = $capacity;
return $this; // returns the current class instance to allow method chaining
}
public function setSpeed($speed) {
$this->speed = $speed;
return $this; // returns the current class instance to allow method chaining
}
}
Quando usarlo
I casi d'uso primari per l'utilizzo di Method Chaining si hanno quando si creano lingue specifiche di dominio interne. Il concatenamento di metodi è un elemento fondamentale in Expression Builders e Fluent Interfaces . Non è sinonimo di quelli, però . Il metodo Chaining consente semplicemente a quelli. Citando Fowler:
Ho anche notato un malinteso comune: molte persone sembrano equiparare interfacce fluide con il metodo Chaining. Certamente il concatenamento è una tecnica comune da utilizzare con interfacce fluenti, ma la vera fluidità è molto più di questo.
Detto questo, l'uso del metodo di concatenamento solo per evitare di scrivere l'oggetto host è considerato un odore di codice da molti. Rende API non ovvi, soprattutto quando si mischiano con API non concatenate.
Note aggiuntive
Comando Separazione delle query
Command Query Separation è un principio di design portato avanti da Bertrand Meyer . Dichiara che i metodi che mutano lo stato ( comandi ) non dovrebbero restituire nulla, mentre i metodi che restituiscono qualcosa ( query ) non dovrebbero mutare lo stato. Questo rende più facile ragionare sul sistema. Il metodo Chaining viola questo principio perché stiamo mutando lo stato e restituendo qualcosa.
Getters
Quando si utilizzano le classi che implementano il concatenamento dei metodi, prestare particolare attenzione quando si chiamano i metodi getter (cioè i metodi che restituiscono qualcosa di diverso da $this
). Poiché i getter devono restituire un valore diverso da $this
, concatenare un metodo addizionale a un getter rende la chiamata operativa sul valore ottenuto , non sull'oggetto originale. Mentre ci sono alcuni casi d'uso per i getter concatenati, possono rendere il codice meno leggibile.
Legge di Demetra e impatto sui test
Il concatenamento di metodi come presentato sopra non viola la legge di Demeter . Né ha impatto sui test. Questo perché stiamo restituendo l'istanza dell'host e non qualche collaboratore. È un comune malinteso derivante da persone che confondono il semplice metodo di concatenazione con Fluent Interfaces e Expression Builders . È solo quando Method Chaining restituisce altri oggetti rispetto all'oggetto host che violi Law of Demeter e finisci con i Mock Fests nei tuoi test.