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. 命令也可以用来实现日志和事务系统
相关推荐
刀法如飞13 小时前
Palantir Ontology 存储结构与读写机制原理深入剖析
大数据·设计模式·系统架构
KobeSacre15 小时前
设计模式——七大设计原则
设计模式
倒流时光三十年17 小时前
设计模式 之 责任链模式
设计模式·责任链模式
阿文的代码库19 小时前
桥接设计模式的案例实现
设计模式
乐观的山里娃19 小时前
【设计模式 14】责任链:谁来拍板
设计模式
乐观的山里娃1 天前
【设计模式 08】装饰器:加钱加服务
设计模式
魔法阵维护师1 天前
从零开发游戏需要学习的c#模块,第十章(设计模式入门)
学习·游戏·设计模式·c#
用户356302904871 天前
【设计模式】组合模式——树形结构的统一处理
设计模式
乐观的山里娃2 天前
【设计模式 12】原型:复制成功
设计模式
傻啦嘿哟2 天前
办公Agent与人工审核的“握手协议”:关键操作二次确认的设计模式
设计模式