zoukankan      html  css  js  c++  java
  • 用最简单的例子理解命令模式(Command Pattern)

    假设想让遥控器控制电灯的开关、电视机的开关和切换,该如何做?

     

    所有的开、关、切换都是遥控器发出的指令,把这些指令统一抽象成一个接口。

        public interface IControl
    
        {
    
            void Execute();
    
        }

    把电灯、电视机抽象成类。

        public class Tv
    
        {
    
            public void TurnOn()
    
            {
    
                Console.WriteLine("电视机打开了");
    
            }
    
            public void TurnOff()
    
            {
    
                Console.WriteLine("电视机关闭了");
    
            }
    
            public void SwitchChannel()
    
            {
    
                Console.WriteLine("电视机切换频道");
    
            }
    
        }
    
        public class Light
    
        {
    
            public void TunrOn()
    
            {
    
                Console.WriteLine("电灯打开了");
    
            }
    
            public void TurnOff()
    
            {
    
                Console.WriteLine("电灯关闭了");
    
            }
    
        }
    

    Tv类的TurnOn(),TurnOff(),SwitchChannel(),Light类的TurnOn(),TurnOff(),这些方法都会通过执行IController的Execute方法被触发。把每一种动作抽象成类,并实现IControl接口。

        public class LighOn : IControl
    
        {
    
            private Light _light;
    
            public LighOn(Light light)
    
            {
    
                _light = light;
    
            }
    
            public void Execute()
    
            {
    
                _light.TunrOn();
    
            }
    
        }
    
        public class LightOff : IControl
    
        {
    
            private Light _light;
    
            public LightOff(Light light)
    
            {
    
                _light = light;
    
            }
    
            public void Execute()
    
            {
    
                _light.TurnOff();
    
            }
    
        }
    
        public class TvOn : IControl
    
        {
    
            private Tv _tv;
    
            public TvOn(Tv tv)
    
            {
    
                _tv = tv;
    
            }
    
            public void Execute()
    
            {
    
                _tv.TurnOn();
    
            }
    
        }
    
        public class TvOff : IControl
    
        {
    
            private Tv _tv;
    
            public TvOff(Tv tv)
    
            {
    
                _tv = tv;
    
            }
    
            public void Execute()
    
            {
    
                _tv.TurnOff();
    
            }
    
        }
    
        public class TvSwitch : IControl
    
        {
    
            private Tv _tv;
    
            public TvSwitch(Tv tv)
    
            {
    
                _tv = tv;
    
            }
    
            public void Execute()
    
            {
    
                _tv.SwitchChannel();
    
            }
    
        }        
    

    现在,电视机和电灯有了,触发各种动作的类有了,遥控器该装下这些指令(提供装下指令的方法)并提供方法供客户端调用。

        public class RemoteControl
    
        {
    
            private IList<IControl> onCommands = new List<IControl>();
    
            private IList<IControl> offCommands = new List<IControl>();
    
            private IList<IControl> switchCommands = new List<IControl>();
    
            public void AddOnCommand(IControl control)
    
            {
    
                onCommands.Add(control);
    
            }
    
            public void AddOffCommand(IControl control)
    
            {
    
                offCommands.Add(control);
    
            }
    
            public void AddSwitchCommand(IControl control)
    
            {
    
                switchCommands.Add(control);
    
            }
    
            public void PressOnButton(int number)
    
            {
    
                onCommands[number].Execute();
    
            }
    
            public void PressOffButton(int number)
    
            {
    
                offCommands[number].Execute();
    
            }
    
            public void PressSwitchButton(int number)
    
            {
    
                switchCommands[number].Execute();
    
            }
    
        }
    

     

    客户端的执行逻辑大致是:把电视机、电灯准备好,把各种指令准备好,拿出遥控器把各种指令收纳其中,最后调用遥控器的方法执行各种指令。

        class Program
    
        {
    
            static void Main(string[] args)
    
            {
    
                //命令的接收方
    
                Light light = new Light();
    
                Tv tv = new Tv();
    
                //各种命令
    
                LighOn turnLightOn = new LighOn(light);
    
                LightOff turnLightOff = new LightOff(light);
    
                TvOn turnTvOn = new TvOn(tv);
    
                TvOff turnTvOff = new TvOff(tv);
    
                TvSwitch switchTv = new TvSwitch(tv);
    
                //RemoteConroller组装命令
    
                RemoteControl control = new RemoteControl();
    
                control.AddOnCommand(turnLightOn);
    
                control.AddOnCommand(turnTvOn);
    
                control.AddOffCommand(turnLightOff);
    
                control.AddOffCommand(turnTvOff);
    
                control.AddSwitchCommand(switchTv);
    
                control.PressOnButton(0);
    
                Console.ReadKey();
    
            }
    
        }
    

    总结:命令模式的需求源自想通过一个指令(比如这里IControl的Execute方法)来控制多个类的多个方法,包含了几个要素:
    1、命令:让类的各种方法抽象成类实现一个接口
    2、装配命令:把各种命令放到一个集合中
    3、触发命令:提供方法调用命令集合中的某条命令,让其执行指令
          

  • 相关阅读:
    如何在Infraworks中创建多树种组成的森林
    Autodesk 2013开发者日(DevDays)又要来了 -- 北京(2013年11月7日)和上海(2013年11月11日)
    Mac下的Parallel Windows忘记密码怎么办?
    几个有用的JSON工具
    使用Autodesk OAuth服务在用户认证的示例
    ElasticSearch(九)e代驾使用Elasticsearch流程设计(Yii1版本)
    ElasticSearch(八)Elasticsearch-head 连接不上Elasticsearch的原因和解决方案
    ElasticSearch(七) Elasticsearch在Centos下搭建可视化服务
    Yii1自定义 CGridView 中的操作按钮中 CButtonColumn 选项
    Mysql BLOB、BLOB与TEXT区别及性能影响、将BLOB类型转换成VARCHAR类型
  • 原文地址:https://www.cnblogs.com/darrenji/p/3962024.html
Copyright © 2011-2022 走看看