定義
クライアントからのリクエストをオブジェクトに渡し、さまざまなリクエストでクライアントをパラメータ化できるようにします。変更に適応するために、「動作リクエスター」と「動作実装者」を分離し、両者間の疎結合を実現するために使用されます。変化する要因と一定の要因を分離します。
Role
Command
はコマンドのインターフェースを定義し、実行方法を宣言します。
ConcreteCommand
コマンド インターフェイス実装オブジェクトは「仮想」実装であり、通常はレシーバーを保持し、コマンドによって実行される操作を完了するためにレシーバーの関数を呼び出します。
Receiver
Receiver、実際にコマンドを実行するオブジェクト。コマンドに必要な対応する機能を実装できる限り、どのクラスもレシーバーになることができます。
Invoker
はリクエストを実行するためにコマンド オブジェクトを必要とし、通常はコマンド オブジェクトを保持し、多くのコマンド オブジェクトを保持できます。ここは、クライアントが実際にコマンドをトリガーし、対応する操作を実行するようコマンドに要求する場所であり、コマンド オブジェクトへの入り口に相当します。
クライアント
特定のコマンドオブジェクトを作成し、コマンドオブジェクトの受信者を設定します。これは従来の意味でのクライアントではなく、コマンド オブジェクトとレシーバーをアセンブルしていることに注意してください。実際にコマンドを使用するクライアントが Invoker からの実行をトリガーするため、おそらくこのクライアントをアセンブラと呼ぶ方がよいでしょう。
利点
1. オブジェクト間の結合を軽減します。
2. 新しいコマンドをシステムに簡単に追加できます。
3. 組み合わせコマンドの設計が容易になります。
4. 同じメソッドを呼び出して異なる関数を実装する
欠点
コマンド モードを使用すると、一部のシステムで特定のコマンド クラスが多すぎる可能性があります。コマンドごとに特定のコマンド クラスを設計する必要があるため、システムによっては多数の特定のコマンド クラスが必要になる場合があり、これがコマンド パターンの使用に影響します。
該当する状況
1. システムは、発信者と受信者が直接対話しないように、リクエストの発信者とリクエストの受信者を切り離す必要があります。
2. システムはリクエストを指定し、リクエストをキューに入れ、さまざまなタイミングでリクエストを実行する必要があります。
3. システムはコマンドの元に戻す (Undo) 操作と回復 (Redo) 操作をサポートする必要があります。
4. システムは一連の操作を組み合わせる必要があります。つまり、マクロ コマンドをサポートする必要があります。
アプリケーション
は、オン、オフ、チャンネル変更のコマンドを使用してテレビの動作をシミュレートします。コードは次のとおりです
//执行命令的接口 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(); } }
実行結果
テレビのチャンネルは2です
テレビはオフです