• C#


    命令模式

    问题场景

    一个遥控器有1个插槽,插槽对应了两个按钮,一个on,一个off,插槽可以临时插入一个命令,当点击遥控器的on或off按钮时就会调用命令,命令调用某个对象的方法来执行具体的操作。

    总结模式

    一个对象只需存储命令和执行命令,它不需要知道命令执行的是什么逻辑,它只关心命令的存储和调用,具体执行的是什么操作应该由命令对象自己去和目标对象沟通。这个模式可以方便的执行命令,今后有新需求,就可以创建新的命令,只要该命令符合命令的抽象,通过把新命令注入到字典中就能够得到执行。

    示例代码

    先敲出下面的代码,而不要去设计具体的类型,先考虑可能的调用代码,再设计具体的类型

    //遥控器有插槽和按钮
    //插槽:可以插入一个命令,命令作为遥控器的属性被存取
    //按钮:执行命令,用遥控器的ButtonClick模拟按钮的点击
    //执行命令可以控制某个电器装置
    RemoteControl remoteControl = new RemoteControl( ); //遥控器

    //电灯提供on和off方法
    Light light = new Light( );

    //命令,持有对电灯的引用,所以可以调用电灯的on和off方法
    LightOnCmd lightOnCmd = new LightOnCmd( light );
    LightOffCmd lightOffCmd = new LightOffCmd( light );

    remoteControl.OnCmd = lightOnCmd; //遥控器持有开灯的命令
    remoteControl.OffCmd = lightOffCmd; //遥控器持有关灯的命令
    remoteControl.ButtonOnClick( ); //触发遥控器上的On按钮
    remoteControl.ButtonOffClick( );//触发遥控器上的Off按钮

    有了以上的思考,现在开始具体的类型结构设计

    //命令的抽象
    public interface ICommand
    {
        void Execute( );
    }

    //开灯命令的具象
    public class LightOnCmd : ICommand
    {
        private Light Light;
        public LightOnCmd( Light light ) { Light = light; }
        public void Execute( ) { Light.On( ); }
    }

    //关灯命令的具象
    public class LightOffCmd : ICommand
    {
        private Light Light;
        public LightOffCmd( Light light ) { Light = light; }
        public void Execute( ) { Light.Off( ); }
    }

    //灯对象提供开关方法,供命令调用
    public class Light
    {
        public void On( ) { Console.WriteLine( "灯亮" ); }
        public void Off( ) { Console.WriteLine( "灯灭" ); }
    }

    //遥控器
    public class RemoteControl
    {
        public ICommand OnCmd; //通过属性注入命令
        public ICommand OffCmd; //通过属性注入命令

        public void ButtonOnClick( ) { OnCmd.Execute( ); }
        public void ButtonOffClick( ) { OffCmd.Execute( ); }
    }

    改进版:一次注入多个命令

    //命令的抽象
    public interface ICommand
    {
        void Execute( );
    }

    //开灯命令的具象
    public class LightOnCmd : ICommand
    {
        private Light Light;
        public LightOnCmd( Light light ) { Light = light; }
        public void Execute( ) { Light.On( ); }
    }

    //关灯命令的具象
    public class LightOffCmd : ICommand
    {
        private Light Light;
        public LightOffCmd( Light light ) { Light = light; }
        public void Execute( ) { Light.Off( ); }
    }

    //灯对象提供开关方法,供命令调用
    public class Light
    {
        public void On( ) { Console.WriteLine( "灯亮" ); }
        public void Off( ) { Console.WriteLine( "灯灭" ); }
    }

    //遥控器
    public class RemoteControl
    {
        public Dictionary<string, ICommand> Cmds;
        private ICommand Cmd;
        //通过构造函数注入一组命令
        public RemoteControl( Dictionary<string, ICommand> cmds )
        {
            Cmds = cmds;
        }

        public void ButtonOnClick( string cmdOnKey )
        {
            Cmd = Cmds[cmdOnKey];
            if (Cmd != null)
            {
                Cmd.Execute( );
            }
        }
        public void ButtonOffClick( string cmdOffKey )
        {
            Cmd = Cmds[cmdOffKey];
            if (Cmd != null)
            {
                Cmd.Execute( );
            }
        }
    }

    public class Programe
    {
        static void Main( string[] args )
        {
            Light light = new Light( );
            Dictionary<string, ICommand> cmds = new Dictionary<string, ICommand>
        {
            { "LightOn", new LightOnCmd(light) },
            { "LightOff", new LightOffCmd(light) }
        };
            RemoteControl remoteControl = new RemoteControl( cmds );
            remoteControl.ButtonOnClick( "LightOn" );
            remoteControl.ButtonOffClick( "LightOff" );
        }
    }

    命令宏:当按下一个On按钮,可以打开电灯、再打开恒温器和电视机,这一组宏指令可以通过定义一个宏命令类来完成,具体略。

    C# - 设计模式目录

  • 相关阅读:
    工作中问题的总结1
    linux问题故障
    时间转换
    Tips
    总结
    方向
    同步&异步-阻塞&非阻塞
    IO 之 mark()、reset()
    GC日志分析
    JDK 部分工具使用方法
  • 原文地址:https://www.cnblogs.com/myrocknroll/p/8596889.html
Copyright © 2020-2023  润新知