Head First设计模式(六) 设计原则 命令模式

命令模式:

命令模式把请求封装为对象,以便用不同的请求、队列或者日志请求来参数化其他对象,并支持可撤销的操作。

NoCommand:

Nocommand是一个**空对象(null object)**的例子。当你不想返回一个有意义的对象时,以及你要把处理null的责任从客户移除时,空对象就很有用。例如,在我们的遥控器中,没有一个有意义的对象来分配给每个槽,因此我们提供一个NoCommand对象作为替身,在excute()方法被调用时,不做任何事情。

你会发现在许多设计模式相关的内容中用到了空对象,有时你甚至会看到"空对象"出现在设计模式列表中。

宏命令:

宏命令(MacroCommand) 中,用命令数组储存一大群命令

当宏被遥控器执行时,一次性执行这些命令。

问: 一定需要接收者 吗?为什么不能让命令对象实现execute()方法的细节?

答: 一般来说,我们尽量争取制作**"哑"命令对象** ,它只调用接收者上的一个动作;但是,有很多"聪明"命令对象 的例子,它们实现大多数(如果不是全部的话)履行请求所需的逻辑。无疑,你可以这样做,只是要牢记,调用者和接收者之间不再有同样级别的解耦,你也不能用接收者来参数化命令

问: 我怎样才能实现撤销操作的历史?换句话说,我要能够多次按下撤销按钮。

答: 很棒的问题。其实相当容易,不只是保持一个到上一个已执行命令的引用,而是保持一个之前命令的堆栈 。然后,无论何时按下撤销,调用者把第一项弹出栈,并调用其undo()方法。

问: 通过创建一个PartyCommand,并把执行其**他命令的调用放进PartyCommand的execute()**方法中,我把party模式实现为一个命令,这样可以吗?

答: 可以,但是本质上这是**"硬编码"party模式** 到PartyCommand,干吗要自找麻烦呢?有了宏命令,你可以动态地决定哪一个命令进入宏命令,因此,使用宏命令有更多弹性。一般来说,宏命令是更加优雅的解决方案,代码更少。

命令模式的更多用途:请求队列

命令把一小块计算打包(一个接收者和一组动作 ),然后把它作为头等对象传来传去 。即使在一些客户应用创建命令对象很久之后,计算自身依然可能被调用 。事实上,甚至可以被不同的线程调用

命令模式的更多用途:日志请求

当我们执行命令时,把历史储存在磁盘中 。一旦出现崩溃,就重新加载命令对象,并成批地依次调用它们的execute()方法。

这种记录日志的方式对遥控器来说没有意义,但是,有很多应用调用大型数据结构的动作,不能每一次出现变化都快速保存。通过记录日志,我们可以保存上次检查点之后的所有操作 ,如果系统出状况,把这些操作应用到检查点

要点:

  1. 命令模式把做出请求的对象 从知道如何执行请求的对象解耦
  2. 命令对象处在解耦的中心,封装接收者以及一个(或一组)动作。
  3. 调用者通过调用命令对象的execute()做出请求,这会使得接收者的动作被调用。
  4. 调用者可以用命令参数化 ,甚至可以在运行时动态地进行。
  5. 通过实现一个undo()方法 来把对象重建最后一次执行execute()前的状态,命令可以支持撤销。
  6. 宏命令 是命令模式的一种简单的延申。它允许调用多个命令。同样,宏命令很容易支持undo()。
  7. 在实践中,"聪明"命令对象 并不少见。这些对象自己实现请求,而不是委托给接收者。
  8. 命令也可以用来实现日志和事务系统
相关推荐
canonical_entropy4 小时前
模型驱动架构的数学内核:统一生成与演化的 Y = F(X) ⊕ Delta 不变式
数学·设计模式·架构
小毛驴8504 小时前
软件设计模式-代理模式
设计模式·系统安全·代理模式
雨中飘荡的记忆20 小时前
工厂模式详解
设计模式
Charles_go1 天前
C#42、什么是建造者设计模式
设计模式
烤麻辣烫1 天前
23种设计模式(新手)-3接口隔离原则
java·开发语言·学习·设计模式·intellij-idea
e***U8201 天前
算法设计模式
算法·设计模式
颜酱1 天前
理解编程的设计模式(前端角度)
设计模式
ZHE|张恒1 天前
设计模式(五)原型模式 — 通过克隆快速复制对象,避免复杂初始化
设计模式·原型模式
敖云岚2 天前
【设计模式】简单易懂的行为型设计模式-策略模式
设计模式·策略模式