《Head First设计模式》 读书笔记07 封装调用:命令模式

07 《Head First设计模式》 读书笔记07 封装调用:命令模式

 

问题引入

  有一个附着多组开关按钮的遥控器,带有可编程插槽,每个都可以指定到一个不同的家电装置;有很多厂商开发的各种家电装置控制类;希望创建一组API,让每个插槽控制一个或一组装置。

  考虑:不应该让遥控器知道太多厂商类的细节,否则更多的家电加进来,就必须修改代码。

 

解决方案

  使用命令模式,将动作的请求者从动作的执行者对象中解耦。

  在该问题中,请求者可以是遥控器,而执行者对象就是厂商类其中之一的实例。

  利用“命令对象”,把请求封装成一个特定对象,每个按钮都存储一个命令对象,当按钮被按下的时候,就可以请命令对象做相关的工作。

  遥控器并不需要知道工作内容是什么,只要有个命令对象能和正确的对象沟通,把事情做好就可以了。

 

用实例说明

  在餐厅,顾客将自己的需求写在订单上,由服务员交给厨师,然后厨师按照订单指令准备餐点。

 

定义命令模式

  命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。

  命令模式也支持可撤销的操作。

  命令对象将动作和接收者包进对象中。

 

命令模式的类图

 

 

 

用命令模式实现遥控器问题的类图:

 

 

撤销操作的实现

  在Command接口中加入undo()方法,然后每个具体的命令类都实现这个方法:undo方法中调用的操作和execute()方法中的操作相反,比如on的反面是off。

  遥控器类也要做一些修改:加入新的实例变量记录上一个操作,当按下撤销按钮,就调用该实例变量的undo()方法。

  如果撤销到某一个状态需要记录一些变量值,则在execute()方法中加入保存操作前状态数值的语句,然后在undo()的时候恢复。

  如果想要多次撤销,即撤销到很早以前的状态,可以使用一个堆栈记录操作过程的每一个命令。

 

宏命令

  通过一个键,控制多种操作。

  在宏命令中,用命令数组存储一大堆命令,当这个宏命令被遥控器执行时,就一次性执行数组里的每个命令。

 

命令模式的更多用途

 

队列请求

  命令可以将运算块打包(一个接收者和一组动作),然后将它传来传去,就像是对一般的对象一样。

  我们可以利用这样的特性衍生一些应用,例如:日程安排,线程池,工作队列等。

  想象有一个工作队列:你在一端添加命令,然后另一端则是线程。

  线程从队列中取出命令,调用它的execute()方法,等待这个调用完成,然后将此命令对象丢弃,在取出下一个命令……

 

日志请求

  某些应用需要我们将所有的动作都记录在日志中,并能在系统死机之后,重新调用这些动作恢复到之前的状态。

  通过新增两个方法store()、load(),命令模式就能够支持这一点。

  在Java中,我们可以利用对象的序列化(Serialization)实现这些方法,但是一般认为序列化最好还是只用在对象的持久化上(persistence)。

  怎么做:当我们执行命令的时候,将历史记录储存在磁盘中。一旦系统死机,我们就可以将命令对象重新加载,并成批地依次调用这些对象的execute()方法。

 

题外话:《Head First设计模式》读书笔记系列的更新暂停,我不会告诉你是因为图书馆的书超期并且被人预约了所以我借不到了。年后开学再说吧,希望我能坚持到底。

 

posted @ 2013-01-11 10:18  圣骑士wind  阅读(1179)  评论(0编辑  收藏  举报