Das Command Pattern stellt eine Anfrage als Objekt dar, wodurch Aktionen parametrisiert, eingerichtet, protokolliert, wiederholt oder rückgängig gemacht werden kann, ohne dass Auslöser und Empfänger eng gekoppelt sind.
Die Grundidee
interface Command {
execute(): void;
undo(): void;
}
const command = new BoldCommand(editor);
manager.execute(command);
manager.undo();
Der Manager kennt lediglich das Interface des Commands und muss weder die Details der Textbearbeitung noch die der Dateilöschung kennen. Dadurch bleibt er flexibel, weil er jede konkrete Implementierung austauschen kann, ohne selbst etwas davon zu wissen.
Die Beteiligten
- Command: definiert die Operationen
executeund, sofern sinnvoll,undo. - Konkretes Command: hält den Empfänger sowie die für die Ausführung nötigen Anfragedaten.
- Invoker: führt Commands aus und kann dabei eine Historie führen.
- Empfänger: führt die eigentliche Arbeit aus.
class CommandManager {
private history: Command[] = [];
execute(command: Command) {
command.execute();
this.history.push(command);
}
undo() {
this.history.pop()?.undo();
}
}
Eine effektive Undo‑Implementierung muss ausreichend Zustand sichern, damit sie die vorherige Situation exakt wiederherstellen kann; ein bloßer zweifacher Aufruf derselben Methode liefert selten das gewünschte Gegenstück, weil die ursprünglichen Daten bereits verändert wurden.
Anwendungsfälle
Commands eignen sich besonders für UI‑Aktionen, die über mehrere Auslöser verfügen, für Makro‑Operationen, Hintergrundwarteschlangen und Audit‑Logs – etwa wenn ein Menüeintrag, ein Toolbar‑Button und ein Tastaturkürzel dieselbe Funktion ausführen sollen.
class MacroCommand implements Command {
constructor(private commands: Command[]) {}
execute() {
for (const command of this.commands) command.execute();
}
undo() {
for (const command of [...this.commands].reverse()) command.undo();
}
}
Sie lassen sich zudem zur Unterstützung von Rollback‑Abläufen einsetzen. Allerdings erfordern Datenbanktransaktionen und verteilte Kompensationsmechanismen stärkere Garantien, als eine rein im Speicher geführte Command‑Liste bieten kann.
Wann es passt
Für einen einzelnen UI‑Callback genügt häufig eine Closure. Objekt‑Commands hingegen gewinnen an Bedeutung, sobald dieselbe Aktion von verschiedenen Stellen aus ausgelöst wird oder einen eigenständigen Lebenszyklus besitzt, weil sie dann gespeichert, weitergereicht oder später ausgeführt werden können.
Verwandte Muster
Memento bewahrt Zustands‑Snapshots, während Command Aktionen selbst speichert. Composite ermöglicht es, ein Makro aus mehreren Commands zu bilden. Strategy kapselt einen Algorithmus; Command dagegen kapselt eine Anfrage. Diese Muster adressieren unterschiedliche Probleme, lassen sich jedoch kombinieren – beispielsweise kann ein Composite‑Command Memento‑Objekte nutzen, um Zustände wiederherzustellen.
Fazit
Es macht das Command Pattern Aktionen zu Objekten erster Klasse – ein Ansatz, der sich besonders bewährt, sobald eine Anwendung Historien führen, Warteschlangen verwalten, Makros unterstützen oder eine klare Trennung zwischen Auslöser und Implementierung benötigen.

Comments (0)
Please sign in to leave a comment