模式动机
开关与电灯、排气扇示意图
现实生活
- 相同的开关可以通过不同的电线来控制不同的电器。
- 开关<–>请求发送者。
- 电灯、排气扇<–>请求的最终接收者和处理者。
- 开关和电灯、排气扇之间并不存在直接耦合关系,它们通过电线连接在一起,使用不同的电线可以连接不同的请求接收者。
软件开发
- 按钮<–>请求发送者。
- 事件处理类<–>请求的最终接收者和处理者。
- 发送者与接收者之间引入了新的命令对象(类似电线),将发送者的请求封装在命令对象中,再通过命令对象来调用接收者的方法。
- 相同的按钮可以对应不同的事件处理类。
模式定义
- 命令模式:将一个请求封装成一个对象,从而使我们可以用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。
- 命令模式是一种对象行为型模式,其别名为动作模式或事务模式。
命令模式结构图
角色解释:
- Command:抽象命令类
- ConcreteCommand:具体命令类
- Invoker:调用者
- Receiver:接收者
应用实例
为了用户使用方便,某系统提供了一系列功能键,用户可以自定义功能键的功能,如功能键FunctionButton可以用于退出系统(SystemExitClass),也可以用于打开帮助界面(DisplayHelpClass)。用户可以通过修改配置文件来改变功能键的用途,现使用命令模式来设计该系统,使得功能键类与功能类之间解耦,相同的功能键可以对应不同的功能。
命令抽象类
1 | public abstract class Command { |
退出类
1 | public class SystemExitClass { |
退出命令类
1 | public class ExitCommand extends Command { |
显示文档类
1 | public class DisplayHelpClass { |
显示文档命令类
1 | public class HelpCommand extends Command { |
按钮类
1 | public class FunctionButton { |
客户端测试类
1 | public class Client { |
输出结果
1 | 退出系统~ |
命令模式优点
- 降低系统的耦合度
- 新的命令可以很容易地加入到系统中,符合开闭原则
- 可以比较容易地设计一个命令队列或宏命令(组合命令)
- 为请求的撤销和恢复操作提供了一种设计和实现方案
命令模式缺点
- 使用命令模式可能会导致某些系统有过多的具体命令类(针对每一个请求接收者的调用操作都需要设计一个具体命令类)