设计模式学习笔记十五(Command命令模式)

来源:互联网 发布:js中new dateformat 编辑:程序博客网 时间:2024/05/21 16:59

动机:在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合――比如需要对行为进行“记录、撤销/重做(undo/redo)、事务”等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

意图:将一个请求封装为一个对象,从而使你可用不同的请求对客户(程序,行为请求者)进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

基本Code

public class Document

{

     public  void  ShowText()

     {

     }

}

 

public class Graphics

{

     public  void  DisplayGraphic()

     {

     }

}

//应用程序主干/高层抽象

public class App

{

     public  void  Show()

     {

         Document doc=new Document();

         doc.ShowText(); //直接依赖具体行为实现

         Graphics  graph=new Graphics();

         graph.DisplayGraphic();

     }

}

使用Command模式的Code如下:

//具体实现细节

public class Document

{

     public  void  ShowText()

     {

     }

}

public class Graphics

{

     public  void  DisplayGraphic()

     {

     }

}

//实现Command模式

public  interface  ICommand

{

     void  Show();

     void  Undo();

     void  Redo();

}

//具体化的命令对象――从抽象的意义来讲,DocumentCommand表示一个行为

public class DocumentCommand:ICommand

{

     Document  document;

     public DocumentCommand(Document doc)

     {

         this.document=doc;

     }

    public  void  Show ()

     {

         document.ShowText();

     }

     public  void Undo()

     {

     }

     public  void Redo()

     {

     }

}

//具体化的命令对象――从抽象的意义来讲,GraphicsCommand表示一个行为

public class GraphicsCommand:ICommand

{

     Graphics  graph;

     public GraphicsCommand(Graphics graph)

     {

         this.graph=graph;

     }

     public  void  Show()

     {

         graph.DisplayGraphic();

     }

     public  void Undo()

     {

     }

     public  void  Redo()

     {

     }

}

//应用程序主干/高层抽象

public class App

{

     Stack<ICommand> stack;

     Stack<ICommand> undoList;

     public  void  Show()

     {

         foreach(ICommand cmd in stack)

         {

              cmd.Show();

         }

     }

     public void Undo()

     {

         if (canUndo)

         {

              ICommand cmd=stack.Pop();

              cmd.Undo();

              undoList.Add(cmd);

         }

     }

     public void Redo()

     {

         if (canRedo)

         {

              ICommand cmd=undoList.Pop();

              cmd.Redo();

         }

     }

 

}

Command模式结构图如下:

 

Command模式要点:

1、  Command模式的根本目的在于将“行为请求者”与“行为实现者”解耦,在面向对象语言训,常见的实现手段是“将行为抽象为对象”。

2、  实现Command接口的具体命令对象ConcreateCommand有时候根据需要可能会保存一些额外的状态信息。

3、  通过使用Composite模式,可以将多个“命令”封装为一个“复合命令”MacroCommand

4、  Command模式与C#中的Delegate有些类似。但两者定义行为接口的规范有所区别:Command以面向对象中的“接口――实现”来定义接口规范,更严格,更符合抽象原则;Delegate以函数签名来定义行为接口规范,更灵活,但抽象能力比较弱。

 
原创粉丝点击