设计模式C#实现(十五)——命令模式

 

 

意图

将请求封装成一个对象,客户接受请求参数;可以对请求排队或者记录请求日志,以及可以支持撤销操作

适用性

  • 抽象出待执行的动作以参数化某对象。命令模式是回调机制的一个面向对象的替代品
  • 在不同的时刻指定、排列和执行请求
  • 支持取消操作
  • 支持修改日志
  • 支持事务

结构

命令模式UML

实现

使用遥控器,实现对一个灯的远程遥控。灯有开、关两个操作。

  class Light
    {
        public void On()
        {
            Console.WriteLine("light is on");
        }
        public void Off()
        {
            Console.WriteLine("light is off");
        }
    }

首先抽象出操作类或者接口

  public interface ICommand
    {
        void Execute();
        void Undo();//撤销
    }

对这开、关两个操作请求进行封装,操作需要一个对象作为初始化参数

 class LightOnCommand : ICommand
    {
        private Light _light;
        public LightOnCommand(Light light)
        {
            this._light = light;
        }
        public void Execute()
        {
            _light.On();
        }
        public void Undo()
        {
            _light.Off();
        }
    }
     class LightOffCommand:ICommand
    {
        private Light _light;
        public LightOffCommand(Light light)
        {
            this._light = light;
        }
        public void Execute()
        {
            _light.Off();
        }
        public void Undo()
        {
            _light.On();
        }
    }

遥控器接受请求作为初始化参数

class SimpleRemoteControl
    {
        private ICommand _onSlot;
        private ICommand _offSlot;
        private ICommand _lastCommand;//记录最后一次操作请求
        public void SetCommand(ICommand onCommand,ICommand offCommand)
        {
            _onSlot = onCommand;
            _offSlot = offCommand;
        }
        public void OnButtonWasPressed()
        {
            _onSlot.Execute();
            _lastCommand = _onSlot;
        }
        public void OffButtonWasPressed()
        {
            _offSlot.Execute();
            _lastCommand = _offSlot;
        }
        public void Undo()
        {
            _lastCommand.Undo();
        }
    }

使用封装好的请求对客户(遥控器)进行参数化,使其可以控制灯,也可以封装更多操作,使遥控器可以控制其他物品

 class Program
    {
        static void Main(string[] args)
        {
            SimpleRemoteControl remote = new SimpleRemoteControl();
            Light light = new Light();
            LightOnCommand lightOn = new LightOnCommand(light);
            LightOffCommand lightOff = new LightOffCommand(light);
            remote.SetCommand(lightOn, lightOff);
            remote.OnButtonWasPressed();
            remote.OffButtonWasPressed();
            remote.Undo();//撤销上一步操作
            Console.ReadKey();
        }
    }

运行结果
运行结果

效果

  • 将调用操作的对象与知道如何实现该操作的对象解耦
  • 可以将多个命令装配成一个复合命令
  • 增加新的命令无需修改已有的类

参考

  1. 《Head First 设计模式》
  2. 《设计模式》
posted @ 2016-01-10 15:33 妖刀Dreamcast 阅读(...) 评论(...) 编辑 收藏