你的位置:首页 > ASP.net教程

[ASP.net教程]设计模式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. 《设计模式》