zoukankan      html  css  js  c++  java
  • 设计模式之命令模式

    命令模式可将"动作的请求者"从"动作的执行者"对象中解耦。
    在设计中,采用"命令对象",利用命令对象,把请求封装成一个特定的对象,如果每个按钮都存储一个命令对象,那么当按钮被按下的时候,就可以请命令对象做相关工作了。

    第一个命令对象

    实现命令接口

        /// <summary>
        /// 实现命令接口:让所有命令对象实现相同的包含一个方法的接口
        /// </summary>
        public interface Command
        {
            void execute();
        }
    

    实现一个打开电灯的命令

     public class LightOnCommand : Command
        {
            private Light light;
    
            public LightOnCommand(Light light)//构造方法中传入一个对象,当execute被调用的时候,就由这个对象作为接收者,接受请求。
            {
                this.light = light;
            }
            public void execute()//调用接收对象
            {
                light.@on();
            }
        }
    

    使用命令对象

    public  class SimpleRemoteControl
     {
         private Command slot;//插槽持有命令,这个命令控制着一个装置
    
         public SimpleRemoteControl()
         {
             
         }
    
         public void setCommand(Command command)//用来设置插槽控制的命令
         {
             slot = command;
         }
    
         public void buttonWasPressed()//调用这个方法,使得当前命令衔接插槽被调用
         {
             slot.execute();
         }
     }
    

    简单测试

    static void Main(string[] args)
            {
                SimpleRemoteControl remote=new SimpleRemoteControl();//发出请求
                Light light=new Light();//请求的接收者
                LightOnCommand lightOn=new LightOnCommand(light);//创建一个命令,将接收者传给它
    
                remote.setCommand(lightOn);//把命令传给调用者
                remote.buttonWasPressed();//调用
                Console.ReadKey();
            }
    

    定义命令模式

    命令模式:将请求封装成对象,以便使用不同请求、队列、或者日志来参数化其他对象。命令模式也支持可撤销操作。
    一个命令对象通过在特定接收者上绑定一组动作来封装一个请求。命令对象将动作和接收者包进对象中,这个对象只暴漏出一个execute()方法,当此方法被调用的时候,接收者就会进行这些动作。

    类图


    client:这个客户负责创建一个ConcreteCommand,并设置其接收者。
    Receiver:接收者知道如何进行必要的工作,实现这个请求。任何类都可以当接收者。
    ConcreteCommand:这个ConcreteCommand定义了动作和接收者之间的绑定关系。
    Invoker:这个调用者持有一个命令对象,并在某个时间点调用命令对象的execute方法,将请求实行。
    Command:Command为所有命令声明了一个接口。调用命令对象的execute方法,就可以让接收者进行相关的动作。

    使用反转命令

    使用命令模式,我们还可以使用反转命令,撤销之前操作。

    新增undo()

    在命令接口中,新增undo()用于反转之前操作命令

        public interface Command
        {
            void execute();
    
            void undo();
        }
    

    执行

    public class LightOnCommand : Command
        {
            private Light light;
    
            public LightOnCommand(Light light)//构造方法中传入一个对象,当execute被调用的时候,就由这个对象作为接收者,接受请求。
            {
                this.light = light;
            }
            public void execute()//调用接收对象
            {
                light.@on();
            }
    
            public void undo()
            {
                light.off();
            }
        }
    

    队列请求

    命令可以将运算块打包,然后将它传来传去,就像是一般的对象一样。即使在命令对象被创建许久以后,运算依然可以被调用。这样就可以将它传入队列中使用。
    队列对象不在乎到底做些什么,它们只知道取出命令对象,然后调用其execute()方法。

    日志请求

    某些应用需要我们将所有的动作都记录在日志中,并能在系统死机之后,重新调用这些动作恢复到之前的状态。
    做法:当我们执行命令的时候,将历史记录存储在磁盘中,一旦系统死机,我们就可以将命令对象重新加载,并成批地依次调用这些对象的execute()方法。
    通过使用记录日志,我们可以将上次检查点之后的所有操作记录下来,如果系统出现状况,从检查点开始应用这些操作。

  • 相关阅读:
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
  • 原文地址:https://www.cnblogs.com/Tan-sir/p/8310860.html
Copyright © 2011-2022 走看看