一、命令模式概述
将一个请求封装到一个对象,从而使得可用不同的请求对客户进行参数化。
二、命令模式结构
(1)Command 抽象命令类
(2)ConcreteCommand 具体命令类
(3)Invoker 调用者 / 请求者
请求的发送者,他通过命令对象来执行。一个调用者并不需要在设计时确定其接受者,因此它只与抽象命令类之间存在关联,在程序运行时,将调用命令对象的execute(),间接调用接受者的相关操作。
(4)Receiver 接收者
接收者执行与请求相关的操作,具体实现对请求的业务处理。
未抽象前,实际执行操作内容的对象。
(5)Client 客户类
在客户类中需要创建调用者对象、具体命令类对象,在创建具体命令类对象时指定对应的接受者。发送者和接收者之间没有直接关系,都通过命令对象间接调用。
三、命令模式场景导入与示例代码
场景:在军队中,团长发出作战命令,但不指定谁去执行命令,命令根据接受者的不同去让接受者(战士)去执行命令。
1 /** 2 * 命令接口 3 * @author CL 4 * 5 */ 6 public interface Command { 7 /** 8 * 在真正的项目中可以设计多个方法 9 */ 10 void execute(); 11 } 12 13 /** 14 * 真正的命令 15 * @author CL 16 * 17 */ 18 class ConcreteCommand implements Command { 19 /** 20 * 命令真正的执行者 21 */ 22 private Receiver receiver; 23 24 public ConcreteCommand() { 25 } 26 27 public ConcreteCommand(Receiver receiver) { 28 this.receiver = receiver; 29 } 30 31 @Override 32 public void execute() { 33 //命令执行前或后,进行相关的操作 34 receiver.action(); 35 } 36 37 }
1 /** 2 * 命令的调用者或发起者(相当于例子中的团长) 3 * @author CL 4 * 5 */ 6 public class Invoke { 7 8 private Command command; //也可以通过容器List<Command>容纳很多的命令,进行批处理。 9 //数据库底层的事务管理就是类似的结构! 10 11 public Invoke(Command command) { 12 this.command = command; 13 } 14 15 /** 16 * 下达命令 17 */ 18 public void call() { 19 //命令执行前或后,进行相关的操作 20 //通过命令对象间接调用接收者 21 command.execute(); 22 } 23 24 }
1 /** 2 * 真正的命令执行者(相当于例子中的战士) 3 * @author CL 4 * 5 */ 6 public class Receiver { 7 8 /** 9 * 执行命令 10 */ 11 public void action() { 12 System.out.println("战士去执行作战命令!"); 13 } 14 15 }
测试:
1 /** 2 * 测试命令模式 3 * @author CL 4 * 5 */ 6 public class Client { 7 8 public static void main(String[] args) { 9 //创建具体命令类对象并指定对应的接受者 10 Command command = new ConcreteCommand(new Receiver()); 11 12 Invoke invoke = new Invoke(command); 13 14 invoke.call(); 15 } 16 }
控制台输出:
战士去执行作战命令!
四、命令模式场景开发应用场景
(1)Struts2 中,action 的整个调用过程就是命令模式;
(2)数据库事务机制的底层实现;
(3)命令的撤销和恢复;
(4)…………