Command パターン
リクエスト、命令、あるいは振る舞いそのものをオブジェクトとしてカプセル化することでアクションの要求者と実行者を分離するデザインパターン。
コマンドオブジェクトをパラメータとして渡したり、履歴管理したり、逆に取り消したりすることができる。コマンドオブジェクトは イベント と呼ばれることもある。
Commandパターンは アクションの要求者 と アクションの実行者 を分離する
Command パターンの構成要素
Command
命令を execute()
として定義したインターフェース、もしくは抽象クラス。
Command.java
public interface Command {
public void execute();
}
ConcreteCommand
Command
の具象クラス。
execute()
内で Reciever
の アクションを呼び出す(Receiver
を保持することにより実現)。
ConcreteCommand は Receiver を介して アクションを実行する
LightOnCommand.java
// Concrete Command
public class LightOnCommand implements Command {
// Receiver を保持
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
// Receiver の action() を呼び出すだけ
light.on();
}
}
LightOffCommand.java
// Concrete Command
public class LightOffCommand implements Command {
// Receiver を保持
Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
// Receiver の action() を呼び出すだけ
light.off();
}
}
Receiver(受信者)
Command からアクションの要求を受け取り、アクションの実装を提供する。
ConcreteCommand
によって保持されている。
Light.java
// Receiver
public class Light {
// action()
public void on() {
System.out.println("電気をつける。");
}
// action()
public void off() {
System.out.println("電気を消す。");
}
}
Invoker(呼出者)
クライアントに対してアクション実行のトリガーを提供する。
アクションの実行が要求されると、 Command の execute()
を実行する。
RemoteControl.java
// リモコン
// Invoker(Client と Command の橋渡し役)
public class RemoteControl {
// Invoker は Command を保持している
private Command command;
public void setCommand(Command command) {
this.command = command;
}
// doSomething()
public void pressButton() {
// Invoker は Client と Command の橋渡しをするが、
// 処理の内容や、どの具象クラスの execute() 実行されるか知らない
command.execute();
}
}
Client(クライアント)
アクションの要求者。
Command パターンによってアクションの実行者と分離されているため、アクションを要求するだけ。アクションの詳細に関与しない。
Main.java
// Client
public class Main {
public static void main(String[] args) {
// Receiver のインスタンス化
Light light = new Light();
// ConcreteCommand のインスタンス化
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
// Invoker のインスタンス化
RemoteControl remote = new RemoteControl();
// Command の設定
remote.setCommand(lightOn);
// Invoker にアクションを要求する
remote.pressButton();
// >> 電気をつける。
// Command の設定
remote.setCommand(lightOff);
// Invoker にアクションを要求する
remote.pressButton();
// >> 電気を消す。
}
}