目录
意图
- 将请求封装为对象,从而使您可以对具有不同请求、队列或日志请求的客户端进行参数化,并支持可撤消的操作。
- 将“在对象上调用方法”提升为完整对象状态
- 面向对象的回调
问题
需要在不知道所请求的操作或请求的接收者的情况下向对象发出请求。
讨论
命令将调用操作的对象与知道如何执行操作的对象分离。为了实现这种分离,设计者创建了一个抽象基类,它将接收者(一个对象)与一个动作(一个指向成员函数的指针)映射起来。基类包含一个 execute()
简单地调用接收器上的操作的方法。
Command 对象的所有客户端都将每个对象视为一个“黑匣子”,execute()
只要客户端需要对象的“服务”,只需调用对象的虚拟方法即可。
Command 类包含以下部分的子集:对象、要应用于对象的方法以及应用方法时要传递的参数。然后,命令的“执行”方法使各个部分组合在一起。
命令对象的序列可以组合成复合(或宏)命令。
结构
创建命令的客户端与执行命令的客户端不同。这种分离为命令的定时和排序提供了灵活性。将命令具体化为对象意味着它们可以像任何其他对象一样被传递、暂存、共享、加载到表中,以及以其他方式检测或操作。

命令对象可以被认为是由一个知道需要做什么的客户端创建的“令牌”,然后传递给另一个有资源的客户端。
例子
命令模式允许将请求封装为对象,从而允许客户端使用不同的请求进行参数化。餐馆的“检查”是命令模式的一个例子。服务员或女服务员接受客户的订单或命令,并通过将其写在支票上来封装该订单。然后将订单排队等待短期订单厨师。请注意,每个服务员使用的“检查”垫不依赖于菜单,因此他们可以支持烹饪许多不同项目的命令。

检查清单
- 定义一个带有方法签名的 Command 接口,例如
execute()
. - 创建一个或多个封装以下子集的派生类:“接收者”对象、要调用的方法、要传递的参数。
- 为每个延迟执行请求实例化一个 Command 对象。
- 将 Command 对象从创建者(又名发送者)传递给调用者(又名接收者)。
- 调用者决定何时
execute()
。
经验法则
- 责任链、命令、中介者和观察者,解决了如何将发送者和接收者解耦,但需要权衡取舍。命令通常指定与子类的发送者-接收者连接。
- 责任链可以使用命令将请求表示为对象。
- Command 和 Memento 充当魔法标记,以便在以后传递和调用。在 Command 中,token 代表一个请求;在 Memento 中,它表示对象在特定时间的内部状态。多态性对 Command 很重要,但对 Memento 不重要,因为它的接口非常狭窄,以至于 memento 只能作为值传递。
- 命令可以使用 Memento 来维护撤消操作所需的状态。
- 宏命令可以用 Composite 来实现。
- 在放入历史列表之前必须复制的命令充当原型。
- 命令模式的两个重要方面:接口分离(调用者与接收者分离),时间分离(存储准备就绪的处理请求,稍后将说明)。
本文来自转载,原文链接: