码迷,mamicode.com
首页 > 其他好文 > 详细

命令模式

时间:2015-07-06 12:08:28      阅读:96      评论:0      收藏:0      [点我收藏+]

标签:

1.命令模式为什么存在

假如存在一个项目组用于开发一个客户A需求的项目,项目组一共有三个小组,负责不同的工作,Requirement Group(需求组)用于收集用户需求,Page Group(页面组)负责系统页面,Code Group(逻辑组)负责实现具体的功能实现。需求方把任务交待给项目经理,由项目经理分别找到不同的小组,实现特定的任务。类图如下:

技术分享

这是一种不错的解决方案,但客户的命令是一个String类型,这有非常多的变化,仅仅通过一个字符串来传递命令并不是一个非常好的解决方案。解决方案是:对客户发出的命令进行封装,每个命令是一个对象,避免客户、负责人、组员之间的交流误差,封装后的结果是客户只要说一个命令,相关的组就立即工作,不用思考、解析命令字符串。

技术分享

2.定义

Encapsulate a request as an object,thereby letting you parameterize clients with different requests.queue or log requests.and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排除或者记录请求日志,可以提供命令的撤销和恢复功能。)

技术分享

Receiver接收者角色:该角色就是真正干活的角色,具体到上面的例子就是Group的三个实现类。

Command命令角色:需要执行的所有命令都在这里声明。

Invoker调用者角色:接收到命令并执行命令,在例子中,项目经理就是这个角色。

3.通用代码

  1 namespace ConsoleApplication1
  2 {
  3     /// <summary>
  4     /// 执行者角色
  5     /// </summary>
  6     public abstract class Receiver
  7     {
  8         public abstract void DoSomeThing();
  9     }
 10 
 11     /// <summary>
 12     /// 具体的执行者角色
 13     /// </summary>
 14     public class ConcreteReceiver1 : Receiver
 15     {
 16         public override void DoSomeThing()
 17         {
 18            //具体的业务逻辑
 19             Console.WriteLine("ConcreteReceiver1 DoSomeThing");
 20         }
 21     }
 22 
 23     /// <summary>
 24     /// 具体的执行者角色
 25     /// </summary>
 26     public class ConcreteReceiver2 : Receiver
 27     {
 28         public override void DoSomeThing()
 29         {
 30             Console.WriteLine("ConcreteReceiver2 DoSomeThing");
 31         }
 32     }
 33 
 34     /// <summary>
 35     /// 抽象化角色
 36     /// </summary>
 37     public abstract class Command
 38     {
 39         private readonly Receiver _receiver;
 40 
 41         protected Command(Receiver receiver)
 42         {
 43             _receiver = receiver;
 44         }
 45 
 46         public void Execute()
 47         {
 48             _receiver.DoSomeThing();
 49         }
 50     }
 51 
 52     /// <summary>
 53     /// 具体的命令角色
 54     /// </summary>
 55     public class ConcreteCommand1 : Command
 56     {
 57         public ConcreteCommand1()
 58             :base(new ConcreteReceiver1())
 59         {
 60         }
 61     }
 62 
 63     /// <summary>
 64     /// 具体的命令角色
 65     /// </summary>
 66     public class ConcreteCommand2 : Command
 67     {
 68         public ConcreteCommand2()
 69             : base(new ConcreteReceiver2())
 70         {
 71         }
 72     }
 73 
 74     /// <summary>
 75     /// 调用者角色
 76     /// </summary>
 77     public class Invoker
 78     {
 79         private Command _command;
 80 
 81         public void SetCommand(Command command)
 82         {
 83             _command = command;
 84         }
 85 
 86         public void Action()
 87         {
 88             _command.Execute();
 89         }
 90     }
 91 
 92     class Program
 93     {
 94         static void Main(string[] args)
 95         {
 96             //定义一个调用者角色
 97             Invoker invoker = new Invoker();
 98 
 99             //指定一个具体的命令
100             invoker.SetCommand(new ConcreteCommand1());
101 
102             //修改执行的命令
103             //invoker.SetCommand(new ConcreteCommand2());
104 
105             invoker.Action();
106 
107             Console.ReadKey();
108         }
109     }
110 }

4.注意事项

(1)模式的优缺点

优点

  • 类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只须调用Command抽象类的execute方法即可,不需要了解到底是哪个接收者执行。
  • 可扩展性:Command的子类可以非常容易的扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。

缺点

  • 如果有N个命令,那么Command的子类就有N个,会导致类膨胀。

 

命令模式

标签:

原文地址:http://www.cnblogs.com/JustYong/p/4623802.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!