一、定义:将一个请求分装成一个对象,从而让你使用不同的请求吧客户端参数化,对请求排队 或者记录请求日志,可以提供命令的撤销和恢复功能。Encapsulate a request as an object, thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.
这种设计模式主要是将类间的关系解耦,将请求分装成命令类,命令类负责指挥底层类 怎么样去完成一项工作, 而底层类之负责管理好自己负责的工作,而。不用考虑各项工作的关系,甚至和其他类的协作关系,都由命令类控制。最后命令类都交给Invoker类负责统一调用。在最高层模块中,只要负责发布相应命令,交给Invoker去执行即可。
二、简单代码示例
Command command1 = new Command1(new Labour1()); //制定命令; 高层调用
Command command2 = new Command1(new Labour2());
Command command3 = new Command2();
Invoker invoker=new Invoker();
invoker.setCommand(command1); //将命令交给Invoker执行
System.out.println("The result of command1 "+invoker.getResult());
invoker.setCommand(command2);
System.out.println("The result of command2 "+invoker.getResult());
invoker.setCommand(command3);
System.out.println("The result of command3 "+invoker.getResult());
执行结果
I am dig desperatelyThe result of command1 DoneI am planting desperatelyThe result of command2 DoneI am dig desperatelyI am planting desperatelyThe result of command3 Done
命令封装:
public interface Command { //命令接口
void exec();
}
public class Command1 implements Command { //第一种命令,叫一个劳力去工作 private Worker worker; public Command1(Worker worker) { // TODO Auto-generated constructor stub this.worker = worker; } @Override public void exec() { // TODO Auto-generated method stub worker.work(); }}
public class Command2 implements Command { //第二种命令 叫两个劳力协同工作 private Worker worker1 = new Labour1(); private Worker worker2 = new Labour2(); @Override public void exec() { //先叫挖土的去挖土,再叫种树的去种树 // TODO Auto-generated method stub worker1.work(); worker2.work(); }}
工作类:
public interface Worker { //工作类 只负责做好自己的工作,其他什么都不管
void work();
}
public class Labour1 implements Worker { public void done() { System.out.println("done"); } @Override public void work() { //我只管挖土 // TODO Auto-generated method stub System.out.println("I am dig desperately"); }}
public class Labour2 implements Worker { @Override public void work() { //我只管种树 // TODO Auto-generated method stub System.out.println("I am planting desperately"); }}
对于复杂的类间关系来说,这种设计模式,是的类间结构清晰,各类职责明确单一,对于需求的修改,不会影响高层调用,只要修改相应分装的命令类即可。如:现在我要加一个填土的工人。
public class Labour3 implements Worker {
@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("I am wrapping desperately");
}
}
若要三个工人协同完成种树工作,即先挖坑,在种树,最后填土。只要在第二种命令中 修改两行代码即可,与高层调用无关。甚至可以做到文件替换。public class Command2 implements Command { private Worker worker1 = new Labour1();
private Worker worker2 = new Labour2();
private Worker worker3= new Labour3(); @Override public void exec() { // TODO Auto-generated method stub worker1.work(); worker2.work();
worker3.work(); }}
但对于类间关系简单的应用,例如你只有一种命令,则用此设计模式显得鸡肋,不如直接写在高层调用中。
命令模式对于撤销,重做的响应,只要再分装一条撤销命令即可,然后又底层的类方法中根据日志进行回滚。可以看到命令模式中主要有三种角色,命令发布者,命令执行者和工作人员。发布者发布一条命令给执行者,执行者执行各种命令。所以关键的需求要在命令类中实现,命令类中要能够完成发布者的需求,协调好各个工作人员的工作,而工作人员只负责自己的工作。职责清晰,结构明确。