码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式篇——初探命令模式

时间:2017-12-14 21:06:36      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:技术分享   设备   opened   关闭按钮   closed   关闭   创建   ima   receive   

命令模式介绍


1、命令模式介绍:命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。


PS:个人理解的命令模式就是将“请求”(方法)封装起来,这个请求中,存在一个或者多个接收者,然后把这个对象传递给一个Invoker(调用者)对象,并向外暴露出一个execute()方法,在特定的时刻调用这个execute方法,进而执行封装的请求方法。 这样做的优点就是外界不需要知道Receiver对象进行了哪些操作,我(外界)仅仅调用了execute方法而已;这样就实现了调用对象调用的请求者之间的解耦。

技术分享图片

2、命令模式类图

先大致看看,脑袋里面有个大体印象~~~emmmmmmmm

技术分享图片

3、命令模式实例


现在我们将要实现一个遥控器,用来控制电灯开关,车库门的上下、开关灯等操作。

/// <summary>
/// 定义请求对象接口,对外暴露方法Execute
/// </summary>
public interface ICommand
{
    void Execute();
}
/// <summary>
/// 定义一个电灯类,存在打开、关闭方法
/// </summary>
public class Light
{
    public void On()
    {
        Console.WriteLine("灯打开了");
    }
    public void Off()
    {
        Console.WriteLine("灯关闭了");
    }
}
/// <summary>
/// 电灯打开指令,继承ICommand接口
/// </summary>
public class LightOnCommand : ICommand
{
    public Light _light;
    /// <summary>
    /// 构造函数传入电灯参数
    /// </summary>
    /// <param name="light"></param>
    public LightOnCommand(Light light)
    {
        _light = light;
    }
    /// <summary>
    /// Execute方法将执行电灯的打开操作
    /// </summary>
    public void Execute()
    {
        _light.On();
    }
}
/// <summary>
/// 同理,来一个电灯关闭的指令
/// </summary>
public class LightOffCommand:ICommand
{
    public Light _light;
    public LightOffCommand(Light light)
    {
        _light = light;
    }
    public void Execute()
    {
        _light.Off();
    }
}
技术分享图片
/// <summary>
/// 同理,定义一个车库对象
/// </summary>
public class GarageDoor
{
    public void Up()
    {
        Console.WriteLine("车库门往上拉");
    }
    public void Down()
    {
        Console.WriteLine("车库门往下降");
    }
    public void Stop()
    {
        Console.WriteLine("车库门停止");
    }
    public void lightOn()
    {
        Console.WriteLine("车库灯打开");
    }
    public void lightOff()
    {
        Console.WriteLine("车库灯关闭");
    }
}
GarageDoor对象

 

技术分享图片
public class GarageDoorOpenCommand : ICommand
{
    GarageDoor _garageDoor;
    public GarageDoorOpenCommand(GarageDoor garageDoor)
    {
        _garageDoor = garageDoor;
    }
    public void Execute()
    {
        _garageDoor.Up();
        _garageDoor.lightOn();
    }
}
public class GarageDoorCloseCommand : ICommand
{
    GarageDoor _garageDoor;
    public GarageDoorCloseCommand(GarageDoor garageDoor)
    {
        _garageDoor = garageDoor;
    }
    public void Execute()
    {
        _garageDoor.Down();
        _garageDoor.lightOff();
    }
}
定义车库门操作对象,当然,要继承ICommand对象

接下来让我们来定义一个遥控器:

  public class NoCommand : ICommand
    {
        public void Execute()
        {
            Console.WriteLine("这个操作是个空操作");
        }
    }
    /// <summary>
    /// 定义遥控器
    /// </summary>
    public class RemoteControl
    {
        ICommand[] _icommandOnList;        //一个ICommand 接口数组。 存放打开指令,理解为遥控器插槽 
        ICommand[] _icommandOffList;       //另一个ICommand 接口数组,存放关闭指令。理解为遥控器插槽
        public RemoteControl()
        {
            ICommand noCommand = new NoCommand();
            _icommandOnList = new ICommand[2] { noCommand, noCommand };     //默认将控制另放入"插槽"
            _icommandOffList = new ICommand[2] { noCommand, noCommand };
        }
        public void setCommand(int slot,ICommand onCommand,ICommand offCommand)  //将具体设备指令方法对应位置的插槽
        {
            _icommandOnList[slot] = onCommand;
            _icommandOffList[slot] = offCommand;
        }
        public void onButtonWasPushed(int slot)                                 //按下指定位置的按钮,执行指定打开命令
        {
            _icommandOnList[slot].Execute();
        }
        public void offButtonWasPushed(int slot)                                //按下指定位置的按钮,执行指定打开命令
        {
            _icommandOffList[slot].Execute();
        }
    }

技术分享图片

 从开始我们就说,命令模式支持撤销操作,那现在让我们来加上撤销操作。

修改ICommand接口、

技术分享图片

修改电灯和车库门的指令

技术分享图片

同理,电灯的关闭指令以及车库门相关指令

技术分享图片

接下来,修改遥控器类,添加一个“撤销插槽”

技术分享图片

技术分享图片

好,这样我们就完成了,让我们来测试一下

技术分享图片

 现在我们需要为遥控器添加一个宏命令。按下打开按钮的时候既可以开灯 又可以 拉起车库的门,同理,关闭按钮也可以执行所有的“关闭动作”

首先,然我们来定义一个“宏命令”类,这个类用来执行一组命令或者撤销一组命令~

public class MacroCommand:ICommand          //创建一个宏命令
{
    ICommand[] _Commands;                   //用来存储一组命令
    public MacroCommand(ICommand[] Commands)     
    {
        _Commands = Commands;
    }
    public void Execute()                   //执行一组开的命令
    {
        foreach(var commnad in _Commands)
        {
            commnad.Execute();
        }
    }
    public void Undo()                      //执行一组撤销的命令
    {
        foreach (var commnad in _Commands)
        {
            commnad.Undo();
        }
    }
}

这时候我们需要把电灯,车库的相关命令,放入宏命令中;再把宏命令放入遥控器的插槽“0”中去

NewCommand.RemoteControl remoteControl = new NewCommand.RemoteControl();  //遥控器
NewCommand.Light roomlight = new NewCommand.Light();                      //电灯以及它的指令
NewCommand.LightOnCommand roomLightOnCommand = new NewCommand.LightOnCommand(roomlight);
NewCommand.LightOffCommand roomLightOffCommand = new NewCommand.LightOffCommand(roomlight);

GarageDoor garageDoor = new GarageDoor();                                //车库门以及指令
GarageDoorOpenCommand garageOpenCommand = new GarageDoorOpenCommand(garageDoor);
GarageDoorCloseCommand garageCloseCommand = new GarageDoorCloseCommand(garageDoor);
//把一组打开的命令放入放入宏命令
MacroCommand onMacroCommand = new MacroCommand(new NewCommand.ICommand[] { roomLightOnCommand, garageOpenCommand });
//把一组关闭的命令放入放入宏命令
MacroCommand offMacroCommand = new MacroCommand(new NewCommand.ICommand[] { roomLightOffCommand, garageCloseCommand });
remoteControl.setCommand(0, onMacroCommand, offMacroCommand); //宏命令放入遥控器插槽
Console.WriteLine("打开宏命令");
remoteControl.onButtonWasPushed(0);
Console.WriteLine("关闭宏命令");
remoteControl.offButtonWasPushed(0);
Console.WriteLine("撤销宏命令");
remoteControl.undoButtonWasPushed();

让我们来测试下 =》

技术分享图片

最后来总结下命令模式:

1、命令模式允许我们将动作封装成命令对象,这样我就可以随意存储,传递,调用它们。

2、命令模式将请求者请求对象的执行者解耦,两者通过命令对象来进行沟通。

3、调用者(接收者)通过调用命令对象的execute()方法(本例中)发出请求,请求对象的执行者执行相应的方法。

4、调用者可以接受命令当做参数。

5、命令可以支持撤销,方法是实现一个undo()方法(本例中),回到执行execute()执行前的状态

6、宏命令允许调用多个命令,宏命令的撤销也能撤销多个命令。

7、命令对象可以直接实现请求,不用将工作委托给接收者

设计模式篇——初探命令模式

标签:技术分享   设备   opened   关闭按钮   closed   关闭   创建   ima   receive   

原文地址:http://www.cnblogs.com/liumengchen-boke/p/8018389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!