Command.java
package commands.schlecht;
public interface Command {
String type();
}
Command ist ein Verhaltensmuster, das eine Anfrage in ein eigenständiges Objekt umwandelt, das alle Informationen über die Anfrage enthält.
Diese Transformation ermöglicht es, Anfragen als Methodenargumente zu übergeben, die Ausführung einer Anfrage zu verzögern oder in eine Warteschlange einzureihen sowie rückgängig zu machende Operationen zu unterstützen.
Command.java
package commands.schlecht;
public interface Command {
String type();
}
CommandExecuter.java
package commands.schlecht;
public class CommandExecuter {
public void executeCommand(Command command) {
System.out.println("Executing command: " + command.type());
switch (command.type()) {
case "DELETE_TEXT":
System.out.println("Deleting text...");
break;
case "INSERT_TEXT":
System.out.println("Inserting text...");
break;
// Immer weiter....
default:
System.out.println("Unknown command type: " + command.type());
}
}
public void undoCommand(Command command) {
System.out.println("Undoing command: " + command.type());
}
}
DeleteTextCommand.java
package commands.schlecht.text;
import commands.schlecht.Command;
public class DeleteTextCommand implements Command {
@Override
public String type() {
return "DELETE_TEXT";
}
}
Trennung: Aufrufer und Ausführer einer Aktion werden entkoppelt.
Kapselung: Methode, Parameter und Empfänger werden in einem Objekt gespeichert.
Flexibilität: Aktionen können übergeben, verzögert oder rückgängig gemacht werden.
Command – definiert die Schnittstelle, meist execute().
Concrete Command – konkrete Implementierung einer Aktion.
Receiver – führt die eigentliche Geschäftslogik aus.
Invoker – löst die Command aus.
Client – erstellt und verbindet alle Objekte.
Der Kellner kocht nicht selbst, sondern gibt die Bestellung an die Küche weiter. Genau so delegiert der Invoker die Aktion an den Receiver.
Ein großer Vorteil des Command Patterns ist die Unterstützung von Undo und Redo.
Jede Aktion wird als Command gespeichert
Die Historie wird meist in Stacks verwaltet
Ein Command kann neben execute() auch undo() besitzen
GUI-Komponenten: Buttons, Menüs, Toolbar-Aktionen.
Job Queues: Aufgaben später oder asynchron ausführen.
Undo / Redo: Aktionen rückgängig machen.
Logging: Operationen speichern und erneut abspielen.
S (Single Responsibility):
Jede Klasse hat eine klare Verantwortung — invoker, receiver, command, etc.
O (Open/ Closed):
Neue Befehle können hinzugefügt werden, ohne bestehende Klassen zu verändern.
D (Dependency Inversion):
Aufrufer basieren auf Abstraktionen (Befehl- Schnittstelle) anstatt auf konkreten Klassen.
👍Entkoppelt Sender und Empfänger einer Anfrage.
👍Neue Befehle lassen sich einfach hinzufügen, ohne bestehenden Code zu ändern.
👍Unterstützt Undo/Redo- und Protokollierungsfunktionen.
👍Befehle können zu Makrobefehlen kombiniert werden.
👎Es entstehen oft viele kleine Klassen.
👎Für einfache Projekte kann das Pattern zu komplex sein.
👎Undo erfordert sauberes Zustandsmanagement.
👎Große Command-Historien können Speicher verbrauchen.
👎Nicht jede Aktion mit Seiteneffekten ist leicht rückgängig zu machen.
Es soll eine einfache Fernbedienung implementiert werden, die Folgendes kann:
Wichtige Anforderung: Die Fernbedienung darf nicht wissen, welches Gerät sie steuert. Sie drückt nur Knöpfe.
Zusätzlich: Neue Geräte sollen hinzugefügt werden können, ohne den Code der Fernbedienung zu ändern
Fragen?