简介
命令模式将请求以命令的方式包裹在对象中,并传给调用对象,是一种数据驱动的设计模式,属于行为型模式。
目的:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化;从而可以对请求进行排队或者记录日志,以及支持可撤销的操作。
在软件设计时,经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么,我们只需要在程序运行时指定具体的接收者即可。此时就可以使用命令模式进行设计,能够让请求发送者和请求接收者解耦,让对象之间的调用关系更加灵活。
命令模式可以让发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。这就是命令模式的模式动机。
如何让“行为请求者”和“行为实现者”解耦:将一组行为抽象为对象。
- 行为请求者将行为对象发出
- 不同的行为实现者根据收到的对象选择是否执行
一般来说,行为请求者只有一个,而行为对象和行为实现者有很多
优点:1、降低了系统耦合度; 2、新的命令可以很容易添加到系统里
缺点:使用命令模式可能会导致某些系统有过多的命令类
命令模式结构示意图:
命令模式共设计五个角色:
- Client(即main方法):创建具体命令对象,并确定其接收者
- Command(命令接口):声明了一个抽象命令接口,所有具体命令都需要实现它
- 如此,在设计时,就可以以抽象接口对象代替具体命令对象,然后在实际使用时才传入具体的命令对象
- ConcreteCommand(具体命令对象):定义一个接收者和行为之间的耦合,实现execute()方法,负责调用接收者相应的操作
- Invoker(请求者):负责调用命令对象执行请求,相关的方法叫做行动方法
- Receiver(接收者):负责具体实施和执行一个请求,任何一个类都可以成为接收者,实施和执行请求方法的方法叫做行动方法
实例
建立抽象命令接口Command,两个具体命令实现类OpenCourseVideoCommand、CloseCourseVideoCommand,请求类Staff,接收类CourseVideo,创建客户类Test用于测试
UML类图
抽象命令接口
1 | /** |
请求者类
1 | /** |
可以看到,请求者类中,负责调用命令对象的方法,都直接使用的Command接口类型对象,以便于后续具体操作中可以传入任何Command接口的实现类
具体命令类
1 | /** |
两个具体的命令类分别封装了关闭课程和开启课程的命令
接收者类
1 | /** |
客户端测试
1 | /** |
可以看到,示例中的命令请求者类Staff与具体的命令执行类CourseVideo没有直接耦合关系,即命令模式实现了命令请求类和接收类的解耦
一句话来说,命令模式就是在原来的命令调用者请求——>命令接收者执行模式中插入了命令对象,变为了:命令调用者请求——>命令对象寻找具体执行者——>具体执行者执行,使得命令请求者与命令执行者不再直接耦合了。
参考
- 本文作者: xczll
- 本文链接: https://xczllgit.github.io/2020/03/27/designPattern/2020-03-27-commandPattern/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!