「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