「Command」という英単語は、「命令」を意味します。
このパターンでは、1つもしくは複数の命令を1つのオブジェクトで表現(命令の詳細処理をカプセル化)します。また、命令をオブジェクトとして管理するため、その命令の履歴管理、UNDO(取消し)機能の実装等が容易に行えます。
Commandパターンのクラス図
1. Command.java
public abstract class Command { public void setReceiver(Receiver receiver) {} public abstract void execute(); }
2-1. ConcreteCommandA.java
public class ConcreteCommandA extends Command { private int id; protected Receiver receiver; private final String name = "A"; public ConcreteCommandA(int id) { this.id = id; } public void setReceiver(Receiver receiver) { this.receiver = receiver; } public void execute() { receiver.action(name + ":" + id); } }
2-2. ConcreteCommandB.java
public class ConcreteCommandB extends Command { private int id; protected Receiver receiver; private final String name = "B"; public ConcreteCommandB(int id) { this.id = id; } public void setReceiver(Receiver receiver) { this.receiver = receiver; } public void execute() { receiver.action(name + ":" + id); } }
3. Receiver.java
public interface Receiver { public abstract void action(String msg); }
4. ConcreteReceiver.java
public class ConcreteReceiver implements Receiver { public void action(String msg) { System.out.println(msg); } }
5. Invoker.java
import java.util.Iterator; import java.util.Stack; public class Invoker { private Stack<Command> commands = new Stack<Command>(); public void addCommnad(Command command) { commands.push(command); } public void undoCommnad() { Command command = (Command) commands.pop(); System.out.println(); System.out.println("undo - 削除された命令 ↓"); command.execute(); System.out.println("undo - 削除された命令 ↑"); System.out.println(); } public void execute() { Iterator<Command> it = commands.iterator(); while (it.hasNext()) { it.next().execute(); } } }
6. Client.java
public class Client { public static void main(String[] args) { Command[] commandsA = new Command[5]; Command[] commandsB = new Command[5]; Receiver receiver = new ConcreteReceiver(); Invoker invoker = new Invoker(); for (int i = 0; i < commandsA.length; i++) { commandsA[i] = new ConcreteCommandA(i); commandsA[i].setReceiver(receiver); invoker.addCommnad(commandsA[i]); } for (int i = 0; i < commandsB.length; i++) { commandsB[i] = new ConcreteCommandB(i); commandsB[i].setReceiver(receiver); invoker.addCommnad(commandsB[i]); } invoker.execute(); invoker.undoCommnad(); invoker.execute(); } }
C:\sample\desin_pattern\Command>javac Client.java [Enter] C:\sample\desin_pattern\Command>java Client [Enter] A:0 A:1 A:2 A:3 A:4 B:0 B:1 B:2 B:3 B:4 undo - 削除された命令 ↓ B:4 undo - 削除された命令 ↑ A:0 A:1 A:2 A:3 A:4 B:0 B:1 B:2 B:3