来自 威尼斯国际官方网站 2019-10-09 23:24 的文章
当前位置: 威尼斯国际官方网站 > 威尼斯国际官方网站 > 正文

威尼斯国际官方网站:命令模式,实现命令设计

代码实施

怀有命令对象急需贯彻的接口:

namespace CommandPattern.Abstractions
{
    public interface ICommand
    {
        void Execute();
    }
}

一盏灯:

using System;

namespace CommandPattern.Devices
{
    public class Light
    {
        public void On()
        {
            Console.WriteLine("Light is on");
        }

        public void Off()
        {
            Console.WriteLine("Light is off");
        }
    }
}

调整灯打开的吩咐:

using CommandPattern.Abstractions;
using CommandPattern.Devices;

namespace CommandPattern.Commands
{
    public class LightOnCommand : ICommand
    {
        private readonly Light light;

        public LightOnCommand(Light light)
        {
            this.light = light;
        }

        public void Execute()
        {
            this.light.On();
        }
    }
}

车库门: 

using System;

namespace CommandPattern.Devices
{
    public class GarageDoor
    {
        public void Up()
        {
            Console.WriteLine("GarageDoor is opened.");
        }

        public void Down()
        {
            Console.WriteLine("GarageDoor is closed.");
        }
    }
}

收起车库门命令:

using CommandPattern.Abstractions;
using CommandPattern.Devices;

namespace CommandPattern.Commands
{
    public class GarageDoorOpen : ICommand
    {
        private readonly GarageDoor garageDoor;

        public GarageDoorOpen(GarageDoor garageDoor)
        {
            this.garageDoor = garageDoor;
        }

        public void Execute()
        {
            garageDoor.Up();
        }
    }
}

简言之的遥控器:

using CommandPattern.Abstractions;

namespace CommandPattern.RemoteControls
{
    public class SimpleRemoteControl
    {
        public ICommand Slot { get; set; }
public void ButtonWasPressed()
        {
            Slot.Execute();
        }
    }
}

运作测量试验:

using System;
using CommandPattern.Commands;
using CommandPattern.Devices;
using CommandPattern.RemoteControls;

namespace CommandPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            var remote = new SimpleRemoteControl();
            var light = new Light();
            var lightOn = new LightOnCommand(light);

            remote.Slot = lightOn;
            remote.ButtonWasPressed();

            var garageDoor = new GarageDoor();
            var garageDoorOpen = new GarageDoorOpenCommand(garageDoor);

            remote.Slot = garageDoorOpen;
            remote.ButtonWasPressed();
        }
    }
}

威尼斯国际官方网站 1

 

统一盘算思路

那就须求考虑一下解决方案了:

第一要思量分手关心点(Separation of concerns),  遥控器应该能够分解开关动作并能够发送诉求, 不过它不应有精晓家电和怎么样开关家电等.

而是当前遥控器只可以做开关功用, 那么怎么让它去决定电灯也许音响呢? 大家不想让遥控器知道那几个实际的家电, 更不想写出下边包车型大巴代码:

if slot1 == Light then Light.On()
else if slot1 == Hub....

谈到那就只好提到命令格局(Command 帕特tern)了.

一声令下形式允许你把动作的诉求者和动作的其实实施者解耦. 这里, 动作的央求者就是遥控器, 而实践动作的目标正是有个别家电.

那是怎么解耦的啊? 怎么大概达成啊?

那就要求引入"命令对象(command object)"了. 命令对象会封装在某些对象上(比如次卧的灯)实行有个别动作的诉求(比方开灯). 所以, 假设我们为每一个按键都计划一个命令对象, 那么当开关被按下的时候, 大家就能够调用这一个命令对象去实践有个别动作. 遥控器本身并不知器具体实行的动作是哪些, 它只是有二个下令对象, 这些命令对象了解去对什么样电器去做怎么着的操作. 就这样, 遥控器和电灯解耦了.

07 《Head First设计情势》 读书笔记07 封装调用:命令情势

指令情势定义

指令形式把央浼封装成二个目的, 进而能够选用分化的伸手对任何对象举行参数化, 对诉求排队, 记录央求的野史, 并扶助撤废操作.

类图:

威尼斯国际官方网站 2

效果图:

威尼斯国际官方网站 3

 

恳求队列

威尼斯国际官方网站 4

那个专门的学业行列是这么工作的: 你增加命令到行列的结尾, 在队列的另一端有多少个线程. 线程那样工作: 它们从队列移除二个命令, 调用它的execute()方法, 然后等待调用甘休, 然后扬弃那个命令再赢得贰个新的命令.

那般大家就能够把总计量限制到一定的线程数上边了. 工作行列和做专门的学业的指标也是解耦的.

标题引进

  有叁个沾满多组开关开关的遥控器,带有可编制程序插槽,种种都可以钦命到三个不如的家电装置;有无数商家开荒的种种家电装置调整类;希望创设一组API,让每一种插槽调节八个或一组织设立置。

  考虑:不应该让遥控器知道太多商家类的底细,不然更多的小家用电器加进去,就必需修改代码。

急需更换----三个开关调节三个设备的四个动作

Party Mode (集会格局):

思路是创办一种命令, 它能够实行多少个别的命令

MacroCommand:

using CommandPattern.Abstractions;

namespace CommandPattern.Commands
{
    public class MacroCommand : ICommand
    {
        private ICommand[] commands;

        public MacroCommand(ICommand[] commands)
        {
            this.commands = commands;
        }

        public void Execute()
        {
            for (int i = 0; i < commands.Length; i++)
            {
                commands[i].Execute();
            }
        }

        public void Undo()
        {
            for (int i = 0; i < commands.Length; i++)
            {
                commands[i].Undo();
            }
        }
    }
}

接纳那些MacroCommand:

using System;
using CommandPattern.Abstractions;
using CommandPattern.Commands;
using CommandPattern.Devices;
using CommandPattern.RemoteControls;

namespace CommandPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            var light = new Light();
            var lightOn = new LightOnCommand(light);
            var lightOff = new LightOffCommand(light);
            var garageDoor = new GarageDoor();
            var garageDoorOpen = new GarageDoorOpenCommand(garageDoor);
            var garageDoorClose = new GarageDoorCloseCommand(garageDoor);
            var stereo = new Stereo();
            var stereoOnWithCD = new StereoOnWithCDCommand(stereo);
            var stereoOff = new StereoOffCommand(stereo);

            var macroOnCommand = new MacroCommand(new ICommand[] { lightOn, garageDoorOpen, stereoOnWithCD });
            var macroOffCommand = new MacroCommand(new ICommand[] { lightOff, garageDoorClose, stereoOff });

            var remote = new RemoteControl();
            remote.SetCommand(0, macroOnCommand, macroOffCommand);
            System.Console.WriteLine(remote);

            System.Console.WriteLine("--- Pushing Macro on ---");
            remote.OnButtonWasPressed(0);
            System.Console.WriteLine("--- Pushing Macro off ---");
            remote.OffButtonWasPressed(0);
        }
    }
}

威尼斯国际官方网站 5

 

 

其它

其一种类的代码作者放在这里了: 

 

宏命令

  通过一个键,调整多样操作。

  在宏命令中,用命令数组存款和储蓄一大堆命令,当以此宏命令被遥控器推行时,就三回性施行数组里的各样命令。

品类必要

威尼斯国际官方网站 6

有诸如此比二个可编制程序的最新遥控器, 它有7个可编制程序插槽, 各种插槽可总是不相同的家电设备. 每种插槽对应五个按键: 开, 关(ON, OFF). 别的还或许有贰个大局的吊销按键(UNDO).

当今客商想接纳那几个遥控器来支配不一致厂家的家电, 例如电灯, 热水器, 风扇, 音响等等.

顾客提议让自身编写贰个接口, 能够让这几个遥控器调整插在插槽上的三个或一组设备.

看一下脚下各家厂家都有怎么样家电:

威尼斯国际官方网站 7

主题材料来了, 这么些家用电器并不曾联手的标准....差相当少各自皆有谈得来的一套调控方法.. 何况其后还要加上很八种家电.

注销操作的贯彻

  在Command接口中参预undo()方法,然后每一个具体的命令类都实现这一个艺术:undo方法中调用的操作和execute()方法中的操作相反,比如on的反面是off。

  遥控器类也要做一些修改:出席新的实例变量记录上三个操作,当按下撤除开关,就调用该实例变量的undo()方法。

  如若打消到某八个意况须求记录一些变量值,则在execute()方法中投入保存操作前状态数值的言语,然后在undo()的时候恢复生机。

  假定想要多次收回,即打消到很早从前的情形,可以应用贰个仓房记录操作进度的每一个发令。

一声令下方式其实利用比如

化解方案

  使用命令形式,将动作的诉求者从动作的实践者对象中解耦。

  在该难点中,须求者能够是遥控器,而实施者对象正是厂家类在那之中之一的实例。

  利用“命令对象”,把要求封装成一个特定对象,各样按键都存款和储蓄贰个指令对象,当开关被按下的时候,就可以请命令对象做连锁的办事。

  遥控器并无需知道事行业内部容是哪些,只要有个指令对象能和不易的靶子关联,把工作办好就可以了。

本文由威尼斯国际官方网站发布于威尼斯国际官方网站,转载请注明出处:威尼斯国际官方网站:命令模式,实现命令设计

关键词: