Entwurfsmuster in PHP: Fortgeschrittene Techniken mit Codebeispielen
Entwurfsmuster sind bewährte Lösungen für typische Probleme, die bei der Softwareentwicklung auftreten. Wenn Sie bereits grundlegende Muster (Singleton, Factory, Observer) beherrschen, ist es an der Zeit, die nächste Stufe zu erreichen. In diesem Artikel analysieren wir vier fortgeschrittene Verhaltensmuster in PHP: Strategie, Befehl, Zustand und Verantwortungskette. Sie erfahren, wie sie helfen, flexiblen, wartbaren und skalierbaren Code zu schreiben.
1. Strategie-Muster (Strategy)
Das Strategie-Muster ermöglicht es, eine Familie von Algorithmen zu definieren, jeden zu kapseln und sie austauschbar zu machen. Dies ist besonders nützlich, wenn Sie mehrere Möglichkeiten haben, dieselbe Aufgabe auszuführen, und Sie einfach zwischen ihnen wechseln möchten, ohne die Hauptklasse zu ändern.
Wann verwenden:
- Sie haben mehrere Algorithmusvarianten, die sich zur Laufzeit ändern können.
- Sie möchten umfangreiche bedingte Konstrukte (if-else oder switch) vermeiden.
- Algorithmen können in verschiedenen Teilen der Anwendung wiederverwendet werden.
Beispiel: System zur Berechnung der Versandkosten
Stellen Sie sich vor, Sie haben einen Online-Shop, und die Versandkosten hängen vom gewählten Transportunternehmen ab: Russische Post, DHL oder ein Kurierdienst.
<?php
// Strategie-Schnittstelleinterface ShippingStrategy { public function calculate(float $weight, float $distance): float;}
// Konkrete Strategienclass RussianPostShipping implements ShippingStrategy { public function calculate(float $weight, float $distance): float { return ($weight * 0.5) + ($distance * 0.1); }}
class DHLShipping implements ShippingStrategy { public function calculate(float $weight, float $distance): float { return ($weight * 1.2) + ($distance * 0.3) + 10; }}
class CourierShipping implements ShippingStrategy { public function calculate(float $weight, float $distance): float { return ($weight * 0.8) + ($distance * 0.2) + 5; }}
// Kontextclass Order { private float $weight; private float $distance; private ShippingStrategy $strategy;
public function __construct(float $weight, float $distance, ShippingStrategy $strategy) { $this->weight = $weight; $this->distance = $distance; $this->strategy = $strategy; }
public function setStrategy(ShippingStrategy $strategy): void { $this->strategy = $strategy; }
public function getShippingCost(): float { return $this->strategy->calculate($this->weight, $this->distance); }}
// Verwendung$order = new Order(2.5, 100, new RussianPostShipping());echo "Versand mit der Russischen Post: " . $order->getShippingCost() . " Rubel.";
$order->setStrategy(new DHLShipping());echo "Versand mit DHL: " . $order->getShippingCost() . " Rubel.";?>In diesem Beispiel ändern wir den Berechnungsalgorithmus einfach, ohne die Klasse Order zu berühren. Das Hinzufügen eines neuen Transportunternehmens reduziert sich auf die Erstellung einer neuen Klasse, die das Interface ShippingStrategy implementiert.
2. Befehl-Muster (Command)
Das Befehl-Muster wandelt Anfragen in Objekte um, sodass Clients mit verschiedenen Anfragen parametrisiert, Anfragen in eine Warteschlange gestellt, protokolliert oder Operationen rückgängig gemacht werden können.
Wann verwenden:
- Sie müssen Rückgängig (undo) und Wiederholen (redo) von Operationen implementieren.
- Operationen müssen in eine Warteschlange gestellt oder asynchron ausgeführt werden.
- Sie möchten den Sender einer Anfrage von deren Empfänger trennen.
Beispiel: Texteditor mit Rückgängig-Funktion
<?php
// Befehlsschnittstelleinterface Command { public function execute(): void; public function undo(): void;}
// Empfänger (Receiver)class
```