Command模式

Command模式只是封装了一个没有任何变量的函数.

  • interface Command{ void Excute();}
  • 具有强烈的分解功能的味道.把函数层面的任务提升到了类的层面(一个类仅仅是为了完成一个函数,而且没有该函数外的任何成员).
  • 简单的Command
    • 事件驱动的系统.
      • Sensor(传感器).驱动者.只负责监听事件,并在事件发生后,调用绑定的Command的Excute方法.而不知道具体绑定的是什么样的Command.
      • Command只负责执行具体的命令逻辑.
      • 两者的绑定关系可以定义于系统主体之外(xml文件etc.)
  • 事务操作.
    • 解除了 从用户获取数据,验证并操作数据,业务对象本身的耦合关系.
    • 时间上解耦. 立即执行Validate,而把Transaction对放在一个List中,之后再执行.(用于DB中的夜间执行场景).
  • UnDo
    • 给Command接口添加一个Undo方法.
    • 很容易实现:知道如何去excute命令的代码和如何去undo命令的代码几乎类似.
  • Active Object模式
    • 复制代码
      public interface CommandEngine
          {
              void AddCommand(Command cmd);
          }
      
          public class RTCEngine : CommandEngine
          {
              private List<Command> Commands;
      
              public RTCEngine()
              {
                  this.Commands = new List<Command>();
              }
      
              public void AddCommand(Command cmd)
              {
                  this.Commands.Add(cmd);
              }
      
              /// <summary>
              /// 执行Command队列中的所有命令,直至队列中不再含有任何的Command.
              /// </summary>
              public void Do()
              {
                  while (this.Commands.Count > 0)
                  {
                      var cmd = Commands.First();
                      this.Commands.Remove(cmd);
                      cmd.Excute();
                  }
              }
          }
      复制代码

       

      复制代码
       1 public interface Command
       2     {
       3         void Excute();
       4     }
       5 
       6 
       7 
       8     public class SleepCommand : Command
       9     {
      10         private long sleepTime;
      11         
      12         private CommandEngine engine;
      13         private Command callBack;
      14 
      15         private bool start;
      16         private long startTime;
      17 
      18         public SleepCommand(long timeout, CommandEngine engine, Command callBack)
      19         {
      20             this.sleepTime = timeout;
      21             this.engine = engine;
      22             this.callBack = callBack;
      23 
      24             this.start = false;
      25         }
      26 
      27         #region Command Members
      28 
      29         /// <summary>
      30         /// 执行,根据条件克隆自己或者添加CallBack命令到Engine中去.
      31         /// </summary>
      32         public void Excute()
      33         {
      34             long time = System.DateTime.Now.Ticks;
      35 
      36             //如果还未启动,那么启动自身,同时将自己添加到Engine队列末尾.
      37             if (!start)
      38             {
      39                 this.start = true;
      40                 this.startTime = time;
      41                 engine.AddCommand(this);
      42             }
      43             //如果还没到唤醒时间,那么添加自己到Engine的队列末尾.
      44             if (time - startTime < sleepTime)
      45             {
      46                 engine.AddCommand(this);
      47             }
      48             else
      49             {
      50                 //已经到唤醒时间,将CallBack命令添加到Engine的队列末尾.
      51                 engine.AddCommand(callBack);
      52             }
      53         }
      54 
      55         #endregion
      56     }
      复制代码

       

    • 阻塞式多线程:当一个线程等待一个事件时,它通常使用一些OS调用来阻塞自己直到事件发生.
    • RTC(run-to-completion):
      • 每个Command实例都在下一个Command实例可以运行之前就运行完成了.
      • 意味着Command实例不会阻塞.(如果等待的事件未到来,只是把自己放回到Engine中).
      • Command实例一经运行就一定得完成.所有的Command实例可以共享一个运行时堆栈.(减少内存使用量).

总结. Command模式具有极其的简洁性.但可以用于DB的Transaction操作,设备控制,多线程核心,GUI的do/undo管理.

其有不符合OO范式的味道.对函数的关注超过了类.

 

[Agile Software Development(Principles,Patterns,and Pracitices)]

posted on 2014-05-15 09:47  RobynHYB  阅读(285)  评论(0编辑  收藏  举报

导航