Definition
leitet die Anfrage vom Client an ein Objekt weiter, sodass Sie den Client mit verschiedenen Anfragen parametrisieren können. Wird verwendet, um „Verhaltensanforderer“ und „Verhaltensumsetzer“ zu entkoppeln, um eine lose Kopplung zwischen den beiden zu erreichen und sich an Änderungen anzupassen. Trennen Sie wechselnde und konstante Faktoren.
Rolle
Befehl
Definieren Sie die Schnittstelle des Befehls und deklarieren Sie die Ausführungsmethode.
ConcreteCommand
Das Befehlsschnittstellen-Implementierungsobjekt ist eine „virtuelle“ Implementierung; es enthält normalerweise den Empfänger und ruft die Funktion des Empfängers auf, um die vom Befehl auszuführende Operation abzuschließen.
Empfänger
Empfänger, das Objekt, das den Befehl tatsächlich ausführt. Jede Klasse kann Empfänger werden, solange sie die entsprechenden, vom Befehl geforderten Funktionen implementieren kann.
Invoker
benötigt das Befehlsobjekt, um die Anforderung auszuführen. Es enthält normalerweise das Befehlsobjekt und kann viele Befehlsobjekte enthalten. Hier löst der Client tatsächlich den Befehl aus und erfordert, dass der Befehl die entsprechende Operation ausführt, was dem Zugriff auf das Befehlsobjekt entspricht.
Client
Erstellen Sie ein bestimmtes Befehlsobjekt und legen Sie den Empfänger des Befehlsobjekts fest. Beachten Sie, dass dies kein Client im herkömmlichen Sinne ist, sondern das Befehlsobjekt und den Empfänger zusammenstellt. Vielleicht wäre es besser, diesen Client einen Assembler zu nennen, da der Client, der den Befehl tatsächlich verwendet, die Ausführung vom Invoker auslöst.
Vorteile
1. Reduzieren Sie die Kopplung zwischen Objekten.
2. Neue Befehle können einfach zum System hinzugefügt werden.
3. Es ist einfacher, einen Kombinationsbefehl zu entwerfen.
4. Rufen Sie dieselbe Methode auf, um verschiedene Funktionen zu implementieren
Nachteile
Die Verwendung des Befehlsmodus kann dazu führen, dass einige Systeme zu viele spezifische Befehlsklassen haben. Da für jeden Befehl eine bestimmte Befehlsklasse entworfen werden muss, erfordern einige Systeme möglicherweise eine große Anzahl spezifischer Befehlsklassen, was sich auf die Verwendung von Befehlsmustern auswirkt.
Anwendbare Situationen
1. Das System muss den Anforderungsanrufer und den Anforderungsempfänger entkoppeln, damit Anrufer und Empfänger nicht direkt interagieren.
2. Das System muss Anfragen spezifizieren, Anfragen in die Warteschlange stellen und Anfragen zu unterschiedlichen Zeiten ausführen.
3. Das System muss den Rückgängig-Vorgang (Undo) und den Wiederherstellungsvorgang (Redo) des Befehls unterstützen.
4. Das System muss eine Gruppe von Operationen kombinieren, d. h. Makrobefehle unterstützen.
Die Anwendung
simuliert den Betrieb des Fernsehers mit Befehlen zum Ein- und Ausschalten und zum Wechseln der Kanäle. Der Code lautet wie folgt
//执行命令的接口 public interface Command { void execute(); } //命令接收者Receiver public class Tv { public int currentChannel = 0; public void turnOn() { System.out.println("The televisino is on."); } public void turnOff() { System.out.println("The television is off."); } public void changeChannel(int channel) { this.currentChannel = channel; System.out.println("Now TV channel is " + channel); } } //开机命令ConcreteCommand public class CommandOn implements Command { private Tv myTv; public CommandOn(Tv tv) { myTv = tv; } public void execute() { myTv.turnOn(); } } //关机命令ConcreteCommand public class CommandOff implements Command { private Tv myTv; public CommandOff(Tv tv) { myTv = tv; } public void execute() { myTv.turnOff(); } } //频道切换命令ConcreteCommand public class CommandChange implements Command { private Tv myTv; private int channel; public CommandChange(Tv tv, int channel) { myTv = tv; this.channel = channel; } public void execute() { myTv.changeChannel(channel); } } //可以看作是遥控器Invoker public class Control { private Command onCommand, offCommand, changeChannel; public Control(Command on, Command off, Command channel) { onCommand = on; offCommand = off; changeChannel = channel; } public void turnOn() { onCommand.execute(); } public void turnOff() { offCommand.execute(); } public void changeChannel() { changeChannel.execute(); } } //测试类Client public class Client { public static void main(String[] args) { // 命令接收者Receiver Tv myTv = new Tv(); // 开机命令ConcreteCommond CommandOn on = new CommandOn(myTv); // 关机命令ConcreteCommond CommandOff off = new CommandOff(myTv); // 频道切换命令ConcreteCommond CommandChange channel = new CommandChange(myTv, 2); // 命令控制对象Invoker Control control = new Control(on, off, channel); // 开机 control.turnOn(); // 切换频道 control.changeChannel(); // 关机 control.turnOff(); } }
Ausführungsergebnis
Der Fernseher ist eingeschaltet.
Jetzt ist der Fernsehsender 2
Der Fernseher ist ausgeschaltet.
Zusammenfassung
1 Der Kern des Befehlsmusters besteht darin, den Befehl zu kapseln und die Verantwortung für die Erteilung des Befehls von der Verantwortung für die Ausführung des Befehls zu trennen.
2. Jeder Befehl ist eine Operation: Die anfragende Partei sendet eine Anfrage zur Durchführung einer Operation; die empfangende Partei empfängt die Anfrage und führt die Operation aus.
3. Der Befehlsmodus ermöglicht es der anfragenden Partei und der empfangenden Partei, unabhängig zu sein, sodass die anfragende Partei die Schnittstelle der die Anfrage empfangenden Partei nicht kennen muss, geschweige denn, wie die Anfrage empfangen wird und ob die Operation ausgeführt wird, wann sie ausgeführt wird und wie sie ausgeführt wird.
4. Der Befehlsmodus macht die Anfrage selbst zu einem Objekt, das wie andere Objekte gespeichert und übertragen werden kann.
5. Der Schlüssel zum Befehlsmodus ist die Einführung einer abstrakten Befehlsschnittstelle, und die Senderprogramme für die abstrakte Befehlsschnittstelle können dem Empfänger nur zugeordnet werden.