PHP
Designmuster
Suche…
Einführung
Dieses Thema enthält Beispiele für bekannte, in PHP implementierte Entwurfsmuster.
Methodenverkettung in PHP
Method Chaining ist eine Technik, die in Martin Fowlers Buch Domain Specific Languages beschrieben wird . Method Chaining wird als zusammengefasst
Betrachten Sie diesen nicht-verketteten / regulären Code (aus dem oben genannten Buch nach PHP portiert).
$hardDrive = new HardDrive;
$hardDrive->setCapacity(150);
$hardDrive->external();
$hardDrive->setSpeed(7200);
Mit Method Chaining können Sie die obigen Anweisungen kompakter schreiben:
$hardDrive = (new HardDrive)
->setCapacity(150)
->external()
->setSpeed(7200);
Damit dies funktioniert, müssen Sie nur return $this
in den Methoden zurückgeben, aus denen Sie verketten möchten:
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
}
}
Wann verwenden?
Die hauptsächliche Verwendung von Method Chaining ist das Erstellen interner domänenspezifischer Sprachen. Method Chaining ist ein Baustein in Expression Builders und Fluent Interfaces . Es ist aber nicht gleichbedeutend mit denen . Method Chaining ermöglicht dies nur. Quoting Fowler:
Ich habe auch ein weit verbreitetes Missverständnis bemerkt - viele Leute scheinen fließende Schnittstellen mit Method Chaining gleichzusetzen. Sicher ist das Verketten eine übliche Technik, die bei fließenden Schnittstellen verwendet werden kann, aber wahrer Fluss ist viel mehr als das.
Wenn man das Method Chaining nur verwendet, um das Schreiben des Host-Objekts zu vermeiden, wird dies von vielen als Code-Geruch betrachtet . Es bietet nicht offensichtliche APIs, insbesondere beim Mischen mit nichtverketteten APIs.
Zusätzliche Bemerkungen
Befehlsabfrage-Trennung
Command Query Separation ist ein Konstruktionsprinzip von Bertrand Meyer . Es gibt an, dass Methoden, die den Status ( Befehle ) ändern, nichts zurückgeben sollen, wohingegen Methoden, die etwas zurückgeben ( Abfragen ), den Status nicht ändern dürfen. Dies erleichtert das Nachdenken über das System. Method Chaining verstößt gegen dieses Prinzip, weil wir den Zustand verändern und etwas zurückgeben.
Getter
Wenn Sie Klassen verwenden, die die Verkettung von Methoden implementieren, müssen Sie beim Aufruf von Getter-Methoden (dh Methoden, die etwas anderes als $this
) besondere Vorsicht walten. Da Getter einen anderen Wert als $this
, bewirkt die Verkettung einer zusätzlichen Methode an einen Getter, dass der Aufruf den erhaltenen Wert bearbeitet , nicht das ursprüngliche Objekt. Obwohl es einige Anwendungsfälle für verkettete Getter gibt, kann der Code weniger lesbar sein.
Demetergesetz und Auswirkungen auf die Prüfung
Method Chaining wie oben dargestellt verstößt nicht gegen das Gesetz von Demeter . Es hat auch keine Auswirkungen auf das Testen. Das liegt daran, dass wir die Host-Instanz zurückgeben und nicht einen anderen Mitarbeiter. Es ist ein weit verbreitetes Missverständnis, das von Leuten verursacht wird, die bloße Methodenketten mit fließenden Schnittstellen und Ausdrucks-Generatoren verwechseln. Nur wenn Method Chaining andere Objekte als das Hostobjekt zurückgibt, verstoßen Sie gegen das Gesetz des Demeters und landen bei Ihren Tests mit Mock-Festen.