命令模式与策略模式的UML类图比较接近,先直观的对比一下。左图:命令模式,右图:策略模式。
可以看出,命令模式的“上部分”就是策略模式,是在策略模式的基础上,增加了receiver类型。
命令模式(Command)定义:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
命令模式的优点有:
1、降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。
2、增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,对扩展比较灵活。
3、可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
4、方便实现 Undo 和 Redo 操作。命令模式可以与备忘录模式结合,实现命令的撤销与恢复。
命令类:
1 public interface Command { 2 public void execute(); 3 } 4 5 public class ConcreteCommandA implements Command { 6 private ReceiverA receiver; 7 8 public ConcreteCommandA() { 9 receiver = new ReceiverA(); 10 } 11 12 @Override 13 public void execute() { 14 // TODO Auto-generated method stub 15 receiver.action(); 16 } 17 } 18 19 public class ConcreteCommandB implements Command { 20 private ReceiverB receiver; 21 22 public ConcreteCommandB() { 23 receiver = new ReceiverB(); 24 } 25 26 @Override 27 public void execute() { 28 // TODO Auto-generated method stub 29 receiver.action(); 30 } 31 }
接收者类:
public class ReceiverA { public void action() { System.out.println("A接收命令"); } } public class ReceiverB { public void action() { System.out.println("B接收命令"); } }
命令触发类:
1 public class Invoker { 2 private Command command; 3 4 public void setCommand(Command command) { 5 this.command = command; 6 } 7 8 public Invoker(Command command) { 9 this.command = command; 10 } 11 12 public void call() { 13 command.execute(); 14 } 15 }
调用方式:
1 public class Client { 2 /* 3 * 命令对象command中包含了具体的操作, 4 * 客户端只需要调用命令,无需关心具体的操作。 5 */ 6 public static void main(String[] args) { 7 //扩展点 8 Command command; 9 10 //使用命令A 11 command = new ConcreteCommandA(); 12 13 //稳定代码 14 Invoker invoker = new Invoker(command); 15 invoker.call(); 16 17 //切换命令B 18 command = new ConcreteCommandB(); 19 invoker.setCommand(command); 20 invoker.call(); 21 } 22 }
执行结果: