简述
将 请求对象 与 执行对象 进行解耦,两者通过 命令对象 来进行单向连接 (也就是调用)
// 请求对象: 遥控器
SimpleRemoteControl remote = new SimpleRemoteControl();
// 执行对象: 「灯」
Light light = new Light("Living Room");
// 命令对象: 同时绑定执行对象 (如果略去执行对象,则是"聪明命令对象")
LightOnCommand lightOn = new LightOnCommand(light);
// 执行对象.绑定(命令对象)
remote.setCommand(lightOn);
// 执行对象.执行
remote.buttonWasPressed();
// 执行对象: 「车库门」
GarageDoor garageDoor = new GarageDoor();
// 创建命令对象, 同时绑定执行对象
remote.setCommand(new GarageDoorCloseCommand(garageDoor));
remote.buttonWasPressed();
remote.undoButtonWasPressed();
优点
- 降低耦合度,典型例子有:Runnable接口和线程池
命令对象可以包含执行对象的堆栈或者队列。达到记录与撤销的效果
既可以使用队列来自由编排宏命令,使得实现更加优雅
也可以使用聪明命令对象,硬编排到命令对象,直接实现宏命令
缺点
- 导致系统有过多太过具体的命令类。
典型就是,命令类对应执行类的一个方法,有多少方法就有多少类,过于冗余
实际使用中,聪明命令对象使用更多
感触
感觉命令模式特别像平时使用的 MVC 三层框架
Controller -> Service -> Mapper
- Controller: Receiver
- Service: Command
- Mapper: Invoker
不过有一处明显的区别, Command 是一个接口, 也就代表 一个 Receiver 可以绑定不同的 Command.
牵强附会一下:
- 一个 Controller 包含 一个 Command 数组 或 Map (一个 控制器 可以转发到多个 Command 模型中去)
- 有多个 Service 实现同一个 Command 接口
- 只有一个 Mapper (就算有多个 Mapper 含义也相同, 细粒度是方法)
- 多个 Service 对应这个 Mapper 的不同方法
行为模式
责任链模式 命令模式 迭代器 中介者模式 备忘录模式 观察者模式 状态模式 策略模式 模版方法模式 访问者模式
- 用于处理请求发送者和接收者之间的不同连接方式:
责任链模式、 命令模式、 中介者模式和观察者模式
- 责任链 按照 顺序 将请求动态传递给一系列的潜在接收者, 直至其中一名接收者对请求进行处理
- 命令 在发送者和请求者之间建立单向连接
- 中介者 清除了发送者和请求者之间的直接连接, 强制它们通过一个中介对象进行间接沟通
- 观察者 允许接收者动态地订阅或取消接收请求
- 责任链 可使用命令模式实现管理者(中间). 在这种情况下, 你可以对由请求代表的同一个上下文对象执行许多不同的操作
- 责任链 还有另外一种实现方式, 那就是请求自身就是一个命令对象. 在这种情况下, 你可以对由一系列不同上下文连接而成的链执行相同的操作
-
命令 和 备忘录模式 可实现 “撤销”. 在这种情况下, 命令用于对目标对象执行各种不同的操作, 备忘录用来保存一条命令执行前该对象的状态
-
命令 和 策略模式 看上去很像, 因为两者都能通过某些行为来参数化对象. 但是意图有非常大的不同。
- 你可以使用 命令模式 来将任何操作转换为对象. 操作的参数将成为对象的成员变量. 你可以通过添加中间步骤, 如转换来延迟操作的执行、 将操作放入队列、 保存历史命令或者向远程服务发送命令等
- 另一方面 策略模式 通常可用于描述完成某件事的不同方式, 让你能够在同一个上下文类中切换算法
-
原型模式可用于保存命令的历史记录
-
可以将 访问者模式 视为 命令模式 的加强版本, 其对象可对不同类的多种对象执行操作