SweetDream
高歌一壶新酿酒,醉抱青山不必归。
通过命令模式可以把一个请求封装到一个对象中(ConcreteCommand)。把请求看成是一个一个的对象给了我们很多灵活性。比如:

1.               实现C语言中的回调效果。回调的基本思想就是由系统给我们提供一些接口,也就是常使用的API,这种函数可以将某个其他函数的地址作为其参数之一,可以通过该地址对这个函数进行调用,而被调用的函数就是我们通常所说的回调函数了。在Command模式中做为参数的函数地址就可以用Command对象来替代,被调用的回调函数就是ConcreteCommand要调用的接受者的相关函数。

2.               在不同的时刻指定,排列和执行请求。因为既然把请求封装成了Command对象,所以一个Command对象可以有自己的生存周期。也就可以方便的对他们进行组织。

3.               因为请求都被封装在一个个Command中,所以请求调用的操作造成的影响也单元化了(即一个command造成一个影响,理解起来不混乱),所以这里我们可以方便地添加撤消操作:CommandExecute操作可在实施前将状态存储起来,在撤消操作时这个状态用来消除该操作的影响。Command接口必须添加一个Unexecute操作,该操作撤消上一次Execute造成的影响。执行的命令被存储在一个历史列表中。可以通过向后和向前遍历这一列表并分别调用UnexecuteExecute来实现重数不限的撤消和恢复。为了达到这个目的,ConcreteCommand类可能需要存储额外的状态信息。包括:

           ·接受者对象,它真正执行处理该请求的各操作。

           ·接受者上执行操作的参数。

           ·如果处理请求的操作会改变接受者对象中的某些值,那么这些值也必
            须先存储 起来,接受者还必须提供一些操作,以使该命令可将接
            受者恢复到它先前的状态。

4.               支持修改日志。在Command接口中添加装载操作和存储操作。以后执行一个操作就记录这个Command把它写入日志。以后系统崩溃后,读入这个日志,一条一条执行原来保存在这个日志中的Command,使得系统状态恢复。

5.               一个事务封装了对数据的一组变动。Command模式提供了对事务进行建模的方法。Command有一个公共的接口,使得可以借鉴Composite模式用同一种方式调用所有的事务。

 

 

Command模式的结构图

   

命令模式涉及到五个角色,它们分别是:

Client:创建了一个具体命令(ConcreteCommand)对象并确定其接收者。

Command:声明了一个给所有具体命令类的抽象接口。这是一个抽象角色。

ConcreteCommand:定义一个接受者和行为之间的弱耦合;实现Execute()方法,

负责调用接收考的相应操作。Execute()方法通常叫做执方法。

Invoker:负责调用命令对象执行请求,相关的方法叫做行动方法。

Receiver:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。

 

注意:InvokerCommand接口之间是一对多的关系,所以多个请求者可以对应相同的Command,从而获得相同的操作,比如一个菜单项和一个按钮可以发出同样的命令。 

 

        补充,在Agile中,作者提到了ACTIVE OBJECT模式,这个模式是一个模拟多线程的古老的技术,它的实现就是基于Command模式中方便对命令的排队的特性。用一个ActiveObjectEngine对象来维护一个Command对象的链表。用户可以向这个链表加入新的命令,或者调用Run函数。Run就是遍历这个链表来执行里面的Command。一个Command可以有自己的生存周期。当执行到某个Command的时候,它执行该Command的指定逻辑操作,然后判断是否到自己该结束的时候,如果没到它就把自己克隆并且放到链表的末尾。并继续运行链表的下一个Command。这个链表就这么一直增加,一直运行。直到所有的Command都到了自己的生存期的末端,即到了链表的结尾。它才结束Run。这样每一个不同的Command(与克隆自己添加到链表末尾的Command相区别)就像一个线程。它在一个“时间片”(遍历到它的时候)执行一次操作,然后就添加到链表末尾等待它的下个“时间片”。

posted on 2005-11-28 21:08  SweetDream  阅读(758)  评论(1编辑  收藏  举报