0Pricing
PHP Academy · Lektion

Verhaltensmuster: Strategy, Observer, Command

Modellieren Sie Verhalten und Kommunikation mit Verhaltensmustern.

Verhaltensmuster: Strategy, Observer, Command ist eine kostenlose PHP Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des PHP Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.

Verhalten modellieren

Verhaltensmuster bestimmen, wie Objekte zusammenarbeiten und Verantwortlichkeiten verteilen. Wir konzentrieren uns auf drei Muster, die in realen PHP-Systemen ständig vorkommen:

  • Strategy — einen Algorithmus zur Laufzeit austauschen.
  • Observer — interessierte Listener über Ereignisse informieren.
  • Command — eine Anfrage in ein Objekt umwandeln, das Sie in eine Warteschlange stellen, protokollieren oder rückgängig machen können.

Strategy: die Idee

Das Muster Strategy definiert eine Familie austauschbarer Algorithmen hinter einer gemeinsamen Schnittstelle und ermöglicht es dem Client, zur Laufzeit auszuwählen. Es ersetzt den ausufernden switch unten durch Polymorphie: Der Kontext delegiert an die Strategie, die er gerade enthält.

<?php
// The smell Strategy removes: branching on a type code
function price(string $type, float $base): float {
    switch ($type) {
        case 'standard': return $base + 5;
        case 'express':  return $base + 15;
        default: throw new InvalidArgumentException($type);
    }
}
echo price('express', 10), PHP_EOL; // 25

Strategy im Code

Hier hängen die Versandkosten vom ausgewählten Versanddienstleister ab. Jede Strategie kapselt einen Preisberechnungsalgorithmus; der Kontext bleibt unverändert, wenn Sie einen weiteren Versanddienstleister hinzufügen.

<?php
interface ShippingStrategy { public function cost(float $weight): float; }
final class Standard implements ShippingStrategy {
    public function cost(float $w): float { return 5 + $w * 0.5; }
}
final class Express implements ShippingStrategy {
    public function cost(float $w): float { return 15 + $w * 1.2; }
}

final class Cart {
    public function __construct(private ShippingStrategy $strategy) {}
    public function setStrategy(ShippingStrategy $s): void { $this->strategy = $s; }
    public function quote(float $weight): float { return $this->strategy->cost($weight); }
}

$cart = new Cart(new Standard());
echo $cart->quote(10), PHP_EOL;     // 10
$cart->setStrategy(new Express());
echo $cart->quote(10), PHP_EOL;     // 27

Strategy mit Closures

In PHP benötigt eine Strategy nicht immer eine Klasse. Für einfache Fälle ist ein callable oder die Syntax für First-Class-Callables eine völlig gültige Strategy. Verwenden Sie vollständige Klassen, wenn der Algorithmus einen eigenen Zustand oder Abhängigkeiten hat, und Closures für einfache, zustandslose Entscheidungen.

<?php
$strategies = [
    'asc'  => fn(array $a) => sort($a) ? $a : $a,
    'desc' => fn(array $a) => rsort($a) ? $a : $a,
];
$data = [3, 1, 2];
print_r($strategies['desc']($data)); // [3,2,1]

Observer: die Idee

Das Muster Observer ermöglicht es einem Subjekt, viele Beobachter zu benachrichtigen, wenn sich sein Zustand ändert, ohne zu wissen, um wen es sich handelt. Dadurch werden die Quelle eines Ereignisses und ihre Handler entkoppelt. Das Muster bildet die Grundlage von Ereignissystemen, Hooks und reaktiven Aktualisierungen.

Observer im Code

Das Subjekt verwaltet eine Liste von Beobachtern und ruft bei jedem update() auf. Neue Listener können sich registrieren, ohne die Logik des Subjekts zu ändern.

<?php
interface Observer { public function update(string $event): void; }

final class OrderSubject {
    private array $observers = [];
    public function subscribe(Observer $o): void { $this->observers[] = $o; }
    public function placed(string $id): void {
        foreach ($this->observers as $o) { $o->update("order $id placed"); }
    }
}
final class EmailObserver implements Observer {
    public function update(string $e): void { echo "email: $e" . PHP_EOL; }
}
final class AuditObserver implements Observer {
    public function update(string $e): void { echo "audit: $e" . PHP_EOL; }
}

$subject = new OrderSubject();
$subject->subscribe(new EmailObserver());
$subject->subscribe(new AuditObserver());
$subject->placed('42');

Observer und PSR-14

Modernes PHP setzt Observer häufig über PSR-14-Ereignis-Dispatcher um: Ein Dispatcher leitet ein Ereignisobjekt an registrierte Listener weiter. Das mentale Modell ist dasselbe (Subjekt = Ereignis, Beobachter = Listener), aber ein Dispatcher entkoppelt sie noch stärker und unterstützt stoppbare Ereignisse. SplObserver/SplSubject existieren zwar in der SPL, werden heute aber nur selten verwendet.

Command: die Idee

Das Muster Command kapselt eine Anfrage als Objekt: die Aktion, ihren Empfänger und ihre Parameter. Da die Anfrage nun aus Daten besteht, können Sie sie in eine Warteschlange stellen, protokollieren, erneut ausführen oder rückgängig machen. Das einfachste Command macht eine Absicht lediglich als Wert greifbar, wie unten gezeigt.

<?php
final class SendEmail {
    public function __construct(
        public readonly string $to,
        public readonly string $subject
    ) {}
}
// The request is now data you can store, serialize, or enqueue
$cmd = new SendEmail('user@example.com', 'Welcome');
echo json_encode($cmd), PHP_EOL;

Command im Code

Jedes Command implementiert execute(). Ein Invoker verwaltet die Commands und führt sie aus, ohne an deren konkrete Aufgabe gekoppelt zu sein. Wenn Sie undo() hinzufügen, wird daraus ein vollständiger Rückgängig-Stapel.

<?php
interface Command { public function execute(): string; }

final class Light { public bool $on = false; }
final class TurnOn implements Command {
    public function __construct(private Light $light) {}
    public function execute(): string { $this->light->on = true; return 'light on'; }
}
final class TurnOff implements Command {
    public function __construct(private Light $light) {}
    public function execute(): string { $this->light->on = false; return 'light off'; }
}

final class Invoker {
    private array $queue = [];
    public function add(Command $c): void { $this->queue[] = $c; }
    public function run(): void {
        foreach ($this->queue as $c) { echo $c->execute(), PHP_EOL; }
    }
}

$light = new Light();
$inv = new Invoker();
$inv->add(new TurnOn($light));
$inv->add(new TurnOff($light));
$inv->run();

Command-Busse

Frameworks bauen auf diesem Muster einen Command-Bus auf: Ein Command-DTO wird genau einem Handler übergeben. Middleware rund um den Bus kann einheitlich Transaktionen, Validierung und Logging hinzufügen. Da Commands einfache serialisierbare Objekte sind, kann derselbe Handler synchron ausgeführt oder in eine Warteschlange für einen Worker gestellt werden.

Zwischen ihnen auswählen

  • Strategy: eine Operation, viele austauschbare Algorithmen, die der Aufrufer auswählt.
  • Observer: ein Ereignis, viele unabhängige Reaktionen; die Quelle kennt die Handler nicht.
  • Command: eine Anfrage greifbar machen, damit sie in eine Warteschlange gestellt, protokolliert, erneut ausgeführt oder rückgängig gemacht werden kann.

Sie lassen sich gut kombinieren: Ein Command-Handler kann eine Strategy auswählen und Observer-Ereignisse auslösen.

Schnelltest

Ordnen Sie die Anforderung dem passenden Muster zu.

Zusammenfassung

Sie haben Verhalten mit drei Mustern modelliert: Strategy, um Algorithmen zur Laufzeit auszutauschen (Klassen oder Closures), Observer, um Zustandsänderungen an entkoppelte Listener zu senden (die Grundlage von PSR-14-Dispatchern), und Command, um Anfragen in Objekte umzuwandeln, die Sie in eine Warteschlange stellen, protokollieren und rückgängig machen können (die Grundlage von Command-Bussen). Zusammen halten sie die Zusammenarbeit flexibel und die Verantwortlichkeiten klar.

Häufig gestellte Fragen

Ist die Lektion „Verhaltensmuster: Strategy, Observer, Command“ kostenlos?

Ja — der vollständige Text von „Verhaltensmuster: Strategy, Observer, Command“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des PHP Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Verhaltensmuster: Strategy, Observer, Command“?

Modellieren Sie Verhalten und Kommunikation mit Verhaltensmustern. Du übst PHP Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um PHP Academy zu starten?

Keine Vorkenntnisse erforderlich. PHP Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Verhaltensmuster: Strategy, Observer, Command“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser PHP Academy-Lektion Code schreiben und ausführen?

Ja. Jede PHP Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. SOLID-Prinzipien in der Praxis
  2. Erzeugungsmuster: Factory, Builder, Singleton
  3. Strukturelle Muster: Adapter, Decorator, Facade
  4. Verhaltensmuster: Strategy, Observer, Command
← Zurück zu PHP Academy