Command-Muster
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 70 von 87.
Das Command-Pattern 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 Ihnen, Anfragen als Methodenargumente zu übergeben, die Ausführung einer Anfrage zu verzögern oder in eine Warteschlange zu stellen und rückgängig machbare Operationen zu unterstützen.
Stellen Sie es sich wie ein Restaurant vor: Anstatt dem Koch direkt zu sagen, was er kochen soll, schreiben Sie Ihre Bestellung auf einen Zettel. Der Kellner (invoker) bringt den Zettel (command) in die Küche, wo er in eine Warteschlange eingereiht, priorisiert oder sogar storniert werden kann. Das Muster entkoppelt das Objekt, das die Operation aufruft, von demjenigen, das sie ausführt.
Das Muster besteht aus vier Schlüsselkomponenten: einem Command-Interface, das die execute-Methode deklariert, ConcreteCommand-Klassen, die spezifische Aktionen implementieren, einem Receiver, der die eigentliche Arbeit verrichtet, und einem Invoker, der Befehle auslöst:
interface Command {
void execute();
}class Light { // Empfänger
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}class RemoteControl { // Invoker
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}Der Aufrufer weiß nicht, welche Aktion ausgeführt wird – er ruft einfach nur execute() auf:
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton(); // Ausgabe: Licht ist ANDas Command-Pattern glänzt, wenn Sie Operationen in eine Warteschlange stellen, eine Rückgängig/Wiederholen-Funktionalität implementieren oder Aufgaben für eine spätere Ausführung planen müssen. Jeder Befehl kapselt alles ein, was zur Ausführung einer Aktion erforderlich ist, wodurch Ihr System flexibler und erweiterbarer wird.
Aufgabe
EinfachLassen Sie uns ein intelligentes Hausautomationssystem mit dem Command Pattern bauen! Sie werden ein System erstellen, in dem verschiedene Heimgeräte über Befehle gesteuert werden können, was es ermöglicht, Aktionen in eine Warteschlange zu stellen, auszuführen und sogar für die spätere Verwendung zu speichern – genau wie eine Universalfernbedienung, die nicht wissen muss, wie jedes Gerät intern funktioniert.
Sie werden Ihren Code über vier Dateien organisieren:
Command.java: Definieren Sie dasCommand-Interface, das alle Gerätebefehle implementieren werden. Es sollte eine einzige Methodeexecute()deklarieren, die die Aktion des Befehls ausführt.Devices.java: Erstellen Sie zwei Empfänger-Klassen (Receiver), die Smart-Home-Geräte repräsentieren:Television- hat die MethodenpowerOn(), die"TV is now ON"ausgibt,powerOff(), die"TV is now OFF"ausgibt, undsetChannel(int channel), die"TV channel set to " + channelausgibt.Thermostat- hat die MethodensetTemperature(int temp), die"Thermostat set to " + temp + " degrees"ausgibt, undturnOff(), die"Thermostat turned OFF"ausgibt.Commands.java: Erstellen Sie konkrete Befehlsklassen, die die Geräteoperationen kapseln:TVOnCommand- nimmt einTelevision-Objekt in seinem Konstruktor entgegen und ruftpowerOn()auf, wenn es ausgeführt wird.TVOffCommand- nimmt einTelevision-Objekt in seinem Konstruktor entgegen und ruftpowerOff()auf, wenn es ausgeführt wird.TVChannelCommand- nimmt einTelevision-Objekt und einint channelin seinem Konstruktor entgegen und ruftsetChannel()mit diesem Kanal auf, wenn es ausgeführt wird.ThermostatSetCommand- nimmt einThermostat-Objekt und eineint temperaturein seinem Konstruktor entgegen und ruftsetTemperature()mit diesem Wert auf, wenn es ausgeführt wird.Main.java: Erstellen Sie eineRemoteControl-Klasse (den Invoker), die eine MethodesetCommand(Command cmd)zum Speichern eines Befehls undpressButton()zum Ausführen des gespeicherten Befehls besitzt.In Ihrer Main-Methode erhalten Sie zwei Eingaben: eine TV-Kanalnummer (Integer) und eine Thermostat-Temperatur (Integer).
Erstellen Sie ein
Television- und einThermostat-Objekt. Erstellen Sie eineRemoteControlund demonstrieren Sie das Command Pattern durch:- Setzen eines
TVOnCommandund Drücken der Taste - Setzen eines
TVChannelCommandmit Ihrem eingegebenen Kanal und Drücken der Taste - Setzen eines
ThermostatSetCommandmit Ihrer eingegebenen Temperatur und Drücken der Taste - Setzen eines
TVOffCommandund Drücken der Taste
- Setzen eines
Sie erhalten zwei Eingaben in dieser Reihenfolge: den TV-Kanal (Integer) und die Thermostat-Temperatur (Integer).
Zum Beispiel, bei den Eingaben 5 und 72, wäre Ihre Ausgabe:
TV is now ON
TV channel set to 5
Thermostat set to 72 degrees
TV is now OFFBeachten Sie, wie die RemoteControl niemals direkt mit den Geräten interagiert – sie kennt nur das Command-Interface. Jeder Befehl kapselt alles, was zur Ausführung seiner Aktion benötigt wird, was es einfach macht, neue Geräte und Befehle hinzuzufügen, ohne den Invoker zu ändern!
Probier es selbst
import java.util.Scanner;
// TODO: Erstelle die Klasse RemoteControl (den Invoker) mit:
// - der Methode setCommand(Command cmd), um einen Befehl zu speichern
// - der Methode pressButton(), um den gespeicherten Befehl auszuführen
class RemoteControl {
// TODO: Implementiere RemoteControl
}
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Eingaben lesen
int channel = scanner.nextInt();
int temperature = scanner.nextInt();
// TODO: Erstelle einen Television und einen Thermostat
// TODO: Erstelle eine RemoteControl
// TODO: Demonstriere das Command Pattern:
// 1. Setze einen TVOnCommand und drücke den Knopf
// 2. Setze einen TVChannelCommand mit dem eingegebenen Kanal und drücke den Knopf
// 3. Setze einen ThermostatSetCommand mit der eingegebenen Temperatur und drücke den Knopf
// 4. Setze einen TVOffCommand und drücke den Knopf
scanner.close();
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas this-SchlüsselwortMethodenFelder (Attribute)Konstruktor-MethodeKonstruktor-ÜberladungRückblick – Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (extends)Das super-SchlüsselwortMethoden überschreiben (@Override)Konstruktor-VerkettungDie Object-KlasseEinfache & mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenZusammenfassung - Mitarbeiter-Hierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-InterfaceZusammenfassung – Benutzerdefiniertes Sortieren2Zugriffsmodifikatoren & Kapselung
Überblick über ZugriffsebenenGetter- und Setter-MethodenInformation HidingDas final-SchlüsselwortRückblick – Bankkonto-Manager5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenZusammenfassung – Formenrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, geschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Sealed Classes (Java 17+)11Design Patterns Teil 1
Einführung in Design PatternsSingleton-PatternFactory-PatternBuilder-PatternObserver-PatternStrategy-Pattern14Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung3Klasseneigenschaften & Statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Zusammenfassung – Zähler & Utility6Interfaces & Abstrakte Klassen
Einführung in InterfacesInterfaces implementierenImplementierung mehrerer InterfacesDefault- & statische Methoden in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesZusammenfassung - Zahlungssystem9Generics
Einführung in GenericsGenerische KlassenGenerische MethodenEingeschränkte TypparameterWildcards (?, extends, super)Zusammenfassung – Generische Container12Entwurfsmuster Teil 2
Command-MusterAdapter-MusterDecorator-MusterTemplate-Method-MusterState-MusterComposite-MusterIterator-Muster