命令模式
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
例子:
1、接收者
public class Receiver {
public void action1(){
System.out.println("receiver doing action 1");
}
public void action2(){
System.out.println("receiver doing action 2");
}
}
2、调用者
public class Invoker {
Command command;
public Invoker() {
}
public void setCommand(Command command) {
this.command = command;
}
public void action(){
command.execute();
}
}
3、命令接口
public interface Command {
public void execute();
public void undo();
}
public class Action1Command implements Command {
Receiver receiver;
public Action1Command(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute() {
// TODO Auto-generated method stub
receiver.action1();
}
@Override
public void undo() {
// TODO Auto-generated method stub
}
}
public class Action2Command implements Command {
Receiver receiver;
public Action2Command(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute() {
// TODO Auto-generated method stub
receiver.action2();
}
@Override
public void undo() {
// TODO Auto-generated method stub
}
}
4、客户
public class Client {
public static void main(String args[]){
Receiver r = new Receiver();
Invoker i = new Invoker();
Command c1 = new Action1Command(r);
Command c2 = new Action2Command(r);
i.setCommand(c1);
i.action();
i.setCommand(c2);
i.action();
}
}
进阶:
1、使用空命令来填充暂无意义的客户端。
public class NoCommand implements Command {
@Override
public void execute() {
System.out.println("done none ");
}
@Override
public void undo() {
// TODO Auto-generated method stub
}
}
2、 宏命令扩展
public class MacroCommand implements Command {
Command[] commands;
public MacroCommand(Command[] commands){
this.commands = commands;
}
@Override
public void execute() {
for(int i = 0 ; i < commands.length ;i++){
commands[i].execute();
}
}
@Override
public void undo() {
// TODO Auto-generated method stub
}
}
队列请求:
想象有一个工作队列,你在某一端添加命令,然后另一端则是线程。线程进行下面的动作:从队列中取出一个命令,调用他的execute()方法,等待这个调用完成,然后将此命令对象丢弃,再取出下一个命令。
日志请求:
当执行命令的时候,将历史记录储存在磁盘中。一旦系统死机,我们就可以将命令对象重新加载,并成批地依次调用这些对象的execute()方法。
要点
- 命令模式将发出请求的对象和执行请求的对象解耦。
- 在被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接受者和一个或一组动作。
- 调用者通过调用命令对象的execute()发出请求,这会使得接受者的动作被调用。
- 调用者可以接受命令当做参数,甚至在运行时动态地进行。
- 命令可以支持撤销,做法是实现一个undo()方法来回到execute()被执行前的状态。
- 宏命令是命令的一种简单的衍生,允许调用多个命令。宏方法也可以支持撤销。
- 实际操作时,很常见使用“聪明”命令对象,也就直接实现了请求,而不是将工作委托给接受者。
- 命令也可以用来实现日志和事务系统。