关闭

17.Command(行为型模式)

191人阅读 评论(0) 收藏 举报

【起源】

         耦合存在于实体对象之间,也存在于实体对象与行为之间。

         通常的方法调用,“行为请求者”和“行为实现者”之间呈现紧耦合。但在某些场合(如:需要对对行为进行“记录,undo/redo,事务”操作),需要松耦合。此时,将行为抽象为Command对象,置于“行为请求者”和“行为实现者”之间,使两者都依赖于Command对象。

 

【动机】

         将一个请求封装为一个对象,从而使你可用不同的请求对Client进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。        

 

【核心】

         调用方法需要两个要素:对象,方法名。对象确定数据,方法名确定操作,本质上是指定操作步骤,处理指定数据

         通常的方式为:先指定对象,然后指定方法名,即“对象.方法名”,实现一个动作。

         反过来想,也可以先指定方法名,后指定对象;但是由于方法属于某个对象,对象先于方法存在,所以要将方法单独封装到一个类中,将对象作为该类的参数传入,并用类的Execute方法封装“对象.方法名”。这样就在宏观上实现了“方法名(对象)”,实现相同的动作。

         Command就是单独封装的那个类。这样做的另一个好处是:将动作变成了一个实体,可以控制它的执行时机 。如果不想只想执行动作,就不调用“动作.Execute()”,直到合适的时候,需要执行动作时调用“动作.Execute()”。

         当行为变成一个实体对象后,就可以使用实体类的很多特性 ,比如:晚绑定。即:确定在何时会执行一个动作,但动作的具体内容在运行时指定。

         Command对象是一个实体,“对象.方法名”是一个消息,内涵相同,承载的介质不同。

         对象之间通过“消息”来通信,本质就是传递“动作”,通常是接受到“动作”就立即执行,Command模式将它分解为两个步骤:1.接收“动作” 2.选择时机执行。

 

【代码实例】

 

【模型图】

 

【Command与Delegate的异同】

       Command:1.创建行为类 2.指定行为(抽象层面,粒度大) 3.以业务需要抽象方法,使执行时机延后并可管理;

        Delegate:1.创建委托类代理某类方法(代码层面,粒度更小) 2.以函数签名抽象方法,将实现方式延后指定;

 

【delegate是什么】

         抽象类 是对类的抽象(类包括:属性和行为);

         接口 是对行为的抽象(行为包括:多个方法);

         委托 是对方法的抽象(方法是:一个行为);

         委托的使用:

               1. 先定义委托类型                  delegate void XX_Delegate() ;

               2. 具体的方法                        void XX_Method() ;      void XX_Method2() ;

               3. 定义变量引用该方法            XX_Delegate delegate1 = XX_Method ;

                                                   或: XX_Delegate delegate2 = new XX_Delegate(XX_Method) ;

               4. 一个委托可绑定多个方法      delegate1 += XX_Method2 ;

               5. 也可以取消已绑定的方法      delegate1 -=  XX_Method2 ;

               6. 通过事件可以封装委托,就像通过属性封装字段一样

                                                          public class Cat

                                                          {

                                                             public delegate void XX_Delegate() ;

                                                             public event XX_Delegate Cry;

                                                          }

                   在其它类中可以 “订阅” 这个事件

                                                          public class Mouse

                                                          {

                                                             public Mouse()

                                                             {

                                                                Cat.Cry += new XX_Delegate(this.Run);

                                                             }

                                                             void Run()

                                                             {

                                                                 Console.Write("猫来了,跑之!");

                                                             }

                                                          }

      在代码层面带来了什么?

      1. 将行为实例化,使它可以作为实体来传递

      2. 改变了对象间的通信方式,将“可变的动态过程”变成了“定义好的静态过程”。

                原通信方式:A监控条件 --》满足条件,传递消息给B做处理

                新通信方式:A监控条件 --》将A的消息与B的处理绑定(写命令) --》满足条件,发出消息(发出去执行)

      好文:http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html

 

【Command和Delegate带来的意义】

         原本只有“数据”是实体,可作为参数传递;

         通过Command模式,“行为”也可变成实体;

         C#提供了Delegate,“方法”也可变成实体;

         实体是“看得见,摸得着”的,它们带来的意义是:将程序中的抽象部分变得具体,更利于理解和使用。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:106478次
    • 积分:1860
    • 等级:
    • 排名:千里之外
    • 原创:89篇
    • 转载:10篇
    • 译文:0篇
    • 评论:11条
    年轻人的精神家园