命令模式——HeadFirst设计模式学习笔记

Posted HectorHou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了命令模式——HeadFirst设计模式学习笔记相关的知识,希望对你有一定的参考价值。

命令模式:将“请求”封装成对象,以便使用不同的请求、日志、队列等来参数化其他对象。命令模式也支持撤销操作。

 

设计原则:

  • 把方法的调用封装起来,调用此对象不需要知道它内部具体是如何运行的,只需要知道包装成型的方法
  • 命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开
  • 将“动作请求者”从“动作执行者”中解耦,即将发出请求的对象和接受并执行请求的对象分离开来。两者通过命令对象沟通
  • 命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联

 

特点:

  • 对象只知道通过接口暴露出execute()方法,当此方法调用时,接受者执行具体的动作。对象不知道那个接受者执行了什么动作,只知道操作进行了

 

NoCommand对象:execute()方法为空的对象,即不执行任何操作的对象。客户端处理null操作时交给空对象,而无需做if(command != null)操作。

 

撤销操作:在管理一组操作对象的对象中可以添加一个上一个操作的对象引用,用于追踪最后调用的命令,并通过命令的undo()方法实现撤销。同样在操作命令对象中也可添加局部变量记录上一个状态以实现undo()方法。

可使用堆栈记录操作过程中的每一个命令,实现多次撤销

 

宏命令:同时执行多个命令,软编码,传入命令数组,动态决定哪些命令

 

日志请求:使用命令模式的记录日志,我们可以将上个检查点之后的操作都记录下来,如果系统出现问题,从检查点开始执行命令

队列请求:把一组命令放到队列(先进先出)中,线程从队列中一个一个删除命令,然后调用它的excecute()方法。

 

 

类图:

Command:定义命令的接口,声明执行的方法。
ConcreteCommand:命令接口实现对象,通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。(组合方式)
Receiver:接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
Invoker:要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。
Client:创建具体的命令对象,并且设置命令对象的接收者。真正使用命令的客户端是从Invoker来触发执行。

 

举例:

使用命令模式实现遥控器,遥控器上的不同按钮控制电灯的开关及亮度、天花板风扇的开关及转速等,支持撤销

1、命令接口:Command

1 public interface Command { 
2     public void execute(); 
3 }

2、对Receiver(灯)实现开关命令

 1 public class LightOnCommand implements Command { 
 2     Light light; 
 3     public LightOnCommand(Light light) { 
 4         this.light = light; 
 5     } 
 6     public void execute() { 
 7         light.on(); 
 8     } 
 9 }
10 
11 public class LightOffCommand implements Command { 
12     Light light; 
13     public LightOffCommand(Light light) { 
14         this.light = light; 
15     } 
16     public void execute() { 
17         light.off(); 
18     } 
19 }

3、实现Invoker控制

 1 public class SimpleRemoteControl { 
 2     Command slot; 
 3     public SimpleRemoteControl() {} 
 4     public void setCommand(Command command) { 
 5         slot = command; 
 6     } 
 7     public void buttonWasPressed() { 
 8         slot.execute(); 
 9     } 
10 }

4、Client使用Invoker控制器

1 public class RemoteControlTest { 
2     public static void main(String[] args) { 
3         SimpleRemoteControl remote = new SimpleRemoteControl(); 
4         Light light = new Light(); 
5         LightOnCommand lightOn = new LightOnCommand(light); 
6         remote.setCommand(lightOn); 
7         remote.buttonWasPressed(); 
8         } 
9 }

 

以上是关于命令模式——HeadFirst设计模式学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

策略模式——HeadFirst 设计模式学习笔记

桥接模式——HeadFirst设计模式学习笔记

装饰者模式——HeadFirst 设计模式学习笔记

代理模式——HeadFirst设计模式学习笔记

组合模式——HeadFirst设计模式学习笔记

原型模式——HeadFirst设计模式学习笔记