• 命令模式


    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个,会导致类膨胀。
  • 相关阅读:
    Linux 的特殊变量(2)
    Shell 的特殊变量
    linux shell 基本规范
    Linux C 程序的开发环境
    编译和连接
    编程语言与C语言的简介
    Python条件判断和循环语句
    Python基本数据类型
    Java基本数据类型
    Jmeter(1)下载和安装
  • 原文地址:https://www.cnblogs.com/JustYong/p/4623802.html
Copyright © 2020-2023  润新知