Entwurfsmuster in PHP: Fortgeschrittenes Niveau
\n\nEntwurfsmuster (Design Patterns) sind bewährte Lösungen für typische Probleme, die bei der Softwareentwicklung auftreten. Auf Anfängerniveau lernen Entwickler Singleton, Factory oder Adapter. In komplexen, hochbelasteten oder flexiblen Systemen in PHP sind jedoch leistungsfähigere und abstraktere Muster erforderlich. In diesem Artikel analysieren wir vier fortgeschrittene Muster mit realen Codebeispielen in PHP: Strategie, Fabrikmethode, Beobachter und Zustand.
\n\n1. Strategie-Muster (Strategy)
\n\nZweck: Definiert eine Familie von Algorithmen, kapselt jeden einzelnen und macht sie austauschbar. Ermöglicht die Änderung des Verhaltens eines Objekts zur Laufzeit ohne Änderung seines Codes.
\n\nBeispiel: Ein Zahlungsabwicklungssystem. Wir haben mehrere Zahlungsmethoden: Kreditkarte, PayPal, Kryptowährung. Jede Methode hat ihre eigene Validierungs- und Verarbeitungslogik.
\n\n<?php\n\n// Strategie-Schnittstelle\ninterface PaymentStrategy\n{\n public function pay(float $amount): void;\n public function validate(): bool;\n}\n\n// Konkrete Strategien\nclass CreditCardPayment implements PaymentStrategy\n{\n private string $cardNumber;\n private string $cvv;\n\n public function __construct(string $cardNumber, string $cvv)\n {\n $this->cardNumber = $cardNumber;\n $this->cvv = $cvv;\n }\n\n public function validate(): bool\n {\n // Einfache Prüfung der Kartennummernlänge\n return strlen($this->cardNumber) === 16 && strlen($this->cvv) === 3;\n }\n\n public function pay(float $amount): void\n {\n if (!$this->validate()) {\n throw new \\InvalidArgumentException("Ungültige Kartendaten");\n }\n echo "{$amount} mit Kreditkarte {$this->cardNumber} bezahlt.<br>";\n }\n}\n\nclass PayPalPayment implements PaymentStrategy\n{\n private string $email;\n\n public function __construct(string $email)\n {\n $this->email = $email;\n }\n\n public function validate(): bool\n {\n return filter_var($this->email, FILTER_VALIDATE_EMAIL) !== false;\n }\n\n public function pay(float $amount): void\n {\n if (!$this->validate()) {\n throw new \\InvalidArgumentException("Ungültige PayPal-E-Mail");\n }\n echo "{$amount} mit PayPal ({$this->email}) bezahlt.<br>";\n }\n}\n\n// Kontext (Client)\nclass OrderProcessor\n{\n private PaymentStrategy $strategy;\n\n public function setPaymentStrategy(PaymentStrategy $strategy): void\n {\n $this->strategy = $strategy;\n }\n\n public function processOrder(float $total): void\n {\n if (!isset($this->strategy)) {\n throw new \\RuntimeException("Keine Zahlungsmethode ausgewählt");\n }\n $this->strategy->pay($total);\n }\n}\n\n// Verwendung\n$order = new OrderProcessor();\n$order->setPaymentStrategy(new CreditCardPayment('1234567812345678', '123'));\n$order->processOrder(150.00);\n// Ausgabe: 150 mit Kreditkarte 1234567812345678 bezahlt.\n\n?>\n\nVorteile: Neue Algorithmen (neue Zahlungsmethoden) können einfach hinzugefügt werden, ohne vorhandenen Code zu ändern. Der Code wird flexibel und testbar.
\n\n2. Fabrikmethode-Muster (Factory Method)
\n\nZweck: Definiert eine Schnittstelle zum Erstellen eines Objekts, ermöglicht es Unterklassen jedoch, den Typ des erstellten Objekts zu ändern. Dies ist das grundlegende Muster für alle Erzeugungsmuster.
\n\nBeispiel: Generierung verschiedener Berichtstypen (PDF, HTML, JSON) basierend auf der Benutzeranfrage.
\n\n<?php\n\n// Abstraktes Produkt\ninterface Report\n{\n public function generate(): string;\n}\n\n// Konkrete Produkte\nclass PdfReport implements Report\n