命令模式
Command Pattern:命令模式,是GoF23种设计模式中属于行为型模式的一种。
命令模式:将请求封装为一个对象,并传给调用对象。调用对象寻找可以处理该命令的合适的处理对象,并把该命令传给相应的处理对象执行命令。
命令模式的本质就是将发出请求和处理请求两者分开,一方只负责发出请求,另一方只负责处理请求。达到的目的就是将行为发起者和行为处理者两者解耦合。
结构
结合类图简单分析一下,命令模式一共有四个角色参与:
- 命令角色:这是用来声明执行操作的接口。
- 具体命令角色:用于将一个接收者角色和一个处理命令进行绑定,达到的作用就是效用接收者相应的方法来实现这个命令的处理过程。
- 请求角色:也就是命令应该执行的请求,可以有一个或者多个命令角色对象。
- 接收者角色:自身实现如何处理和之行一个与请求相关的操作的类。
举例
- 命令模式的使用很多,CPU的处理就是按照指令一行行的来的,由我们触发的按键或者执行程序等等发出一连串的指令,而CPU自己执行处理这些我们发出的指令也是命令模式的使用案例。
- 另一个贴近生活的例子就可以是遥控器了,比如电视机的,空调的,投影仪的等等。遥控器就是一个发出命令的入口,而对应的电器就是处理这些命令的接收者。
注意
- 命令模式本质的作用就是解耦合,将发出命令的一方和执行命令的一方两者独立起来。也就是类似于电视机本身周围的按钮操控电视机的话那就是没有解耦合,如果我们使用了遥控器,那就是解耦合,解耦合的会使得程序更为健壮,可维护性也会更强。
- 命令模式既然对命令进行了抽象,那么命令的多少就直接影响了程序的复杂度,如果命令种类多,那么程序的复杂度就会很大。
- 命令模式的另一个扩展就是当系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作的时候,使用命令模式会是一个很好的解决方法。
一个小DEMO
-
场景
二营长,老子的意大利炮呢????团长发号施令,小兵们就得抓紧干活啊不是,一声令下,炮弹嗖的一声直直指向城楼之上。
-
队伍要想带好,士兵必不可少
/** * 命令模式——接收者对象 * 场景中可爱的小兵们 * @author wq */ public class Soldier { // 真实执行操作的部分 public void doSomething() { System.out.println("嘭嘭嘭 BOOM BOOM BOOM"); } }
-
达成规约,制定命令
/** * 命令模式——命令/指令角色对象 * @author wq */ public abstract class Command { // 保存有接收者对象 protected Soldier soldier; public Command(Soldier soldier) { this.soldier = soldier; } // 声明执行操作 public abstract void exeute(); }
-
具体的命令
/** * 命令模式——具体命令/指令角色对象 * 场景中的开炮的指令 * @author wq */ public class Fire extends Command{ public Fire(Soldier soldier) { super(soldier); } @Override public void exeute() { // 命令和命令的接收者进行绑定 需要进行命令的处理 soldier.doSomething(); } }
-
发出请求/发布命令的入口,也是用户(团长)发号施令的实际位置
/** * 命令模式——请求角色对象 * @author wq */ public class Invoker { // 可以包含一个或者多个命令角色对象 private Command command; // 设置命令的方法 public void setCommand(Command command) { this.command = command; } // 发出请求的方法 public void executeCommand() { command.exeute(); } }
-
测试类
/** * 命令模式——测试类 * @author wq */ public class Main { public static void main(String[] args) { // 命令模式需要有接收者对象,也就是执行命令的实际对象 Soldier soldier = new Soldier(); System.out.println("团长: 开炮!!!!"); // 团长创建命令 Command command = new Fire(soldier); // 命令发出 Invoker invoker = new Invoker(); invoker.setCommand(command); // 小兵接受到命令 进行执行 System.out.print("小兵们: "); invoker.executeCommand(); } }
-
测试走一泼
团长: 开炮!!!! 小兵们: 嘭嘭嘭 BOOM BOOM BOOM
完成!!!