将一个请求封装为一个对象,从而使你可以实现用不同请求对客户进行参数化、对请求进行排队或记录请求日志,以及支持可撤销的操作。有时必须向某对象提交请求,但是当前对象并不知道关于被请求的操作或请求的接受者的任何信息。命令模式通过将请求本身变成一个对象向未指定的应用对象提出请求,这个对象可被存储并像其他的对象一样被传递。
命令模式的优势在于,将命令抽象出来成为对象,这些操作就可以在任意时刻被调用,就像使用回调函数一样;命令模式还可以支持取消操作,Command接口添加撤销的操作方法,然后在实现类中记录一个操作的历史列表,这样就可以实现任意次数的取消和重做了;可以让系统支持存储修改日志,当系统崩溃时,这些修改都可以被重做一遍;可以将命令当做一种事务,这些事务又是由命令叠加而成,故使用这种模式可以方便新事务的添加以拓展系统。
public class Receiver {
public void action(){
System.out.println("Do my Action!");
}
}
public interface Command {
public void execute();
}
public class ConcreteCommand implements Command{
private Receiver receiver = null;
public ConcreteCommand(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
receiver.action();
}
}
public class Invoker {
private Command command = null;
public void addCmd(Command command) {
this.command = command;
}
public void doJob(){
command.execute();
}
}
public class Client {
@Test
public void test() {
//create a command and set it's receiver
Receiver receiver = new Receiver();
Command cmd = new ConcreteCommand(receiver);
//link command with invoker
Invoker invoker = new Invoker();
invoker.addCmd(cmd);
//...do a lot of job
invoker.doJob();
}
}
在Command模式中,Command接口定义了命令的基本要求,ConcreteCommand实现了其中一个命令,在Command中包含着一个Receiver,它代表着命令的真是接收者,Invoker是外部系统能看到,且可以被外部系统调用的对象,它的内部包含着Command对象。在对Invoker进行请求时,它会调用Command对象的方法,Command对象再向真实去做这个操作的对象Receiver做出请求。Client是知道Command的receiver的,而且它会将Command和Invoker(被请求执行命令的对象)相互关联起来以方便未来使用。