深入浅出设计模式-006:命令模式(Command Pattern)

    技术2025-01-17  8

    深入浅出设计模式-006:命令模式(Command Pattern)

    一:命令模式可以将“动作的请求者”从“动作的执行者”对象中解耦。    创建命令对象    利用setCommand将命令对象存储在调用者中    利用execute要求调用者执行命令

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

        public class Light{        public String location;        public Light(String location){            this.location = location;        }        public void On(){            Console.WriteLine(location + "/t Light On");        }        public void Off(){            Console.WriteLine(location + "/t Light Off");        }    }

        public interface Command{        //执行命令        void execute();    }    public class LightOnCommand : Command{        Light light;        public LightOnCommand(Light light){            this.light = light;        }        public void execute(){            light.On();        }    }    public class LightOffCommand : Command{        Light light;        public LightOffCommand(Light light){            this.light = light;        }        public void execute(){            light.Off();        }    }    public class SimpleRemoteControl{        Command slot;        public SimpleRemoteControl() { }        //接受命令        public void setCommand(Command command){            slot = command;        }        public void buttonWasPressed(){            slot.execute();        }    }    class Program//此乃客户    {        static void Main(string[] args)        {            //调用者,用来发出请求            SimpleRemoteControl remote = new SimpleRemoteControl();            //创建对象,此对象即请求的接受者            Light light = new Light("1");            //创建命令,            LightOnCommand lightOn = new LightOnCommand(light);

                //将命令传给调用者,即(服务员下单)            remote.setCommand(lightOn);            remote.buttonWasPressed();        }    }

    三:命令模式将发出请求的对象和执行请求的对象解耦    在被解耦的两者之间是通过命令对象进行沟通的,命令对象封装了接受者的一个或一组动作    调用者通过调用命令对象的EXECUTE发出请求,这会使得接受者的动作被调用    调用者可以接受命令当做参数,甚至在运行时动态地进行    命令可以支持撤销,撤销是实现一个UNDO方法来回到EXECUTE被执行前的状态    宏命令是命令的一种简单延伸,允许调用多个命令。宏方法也可以支持撤销。    命令可以用来实现日志和事物系统    public interface Command{        //执行命令        void execute();        void undo();    }    public class NoCommand : Command{        public void execute()        {            return ;        }        public void undo()        {            return;        }    }    public class MacroCommand : Command{        Command[] commands;        public MacroCommand(Command[] commands){            this.commands = commands;        }        public void execute(){            for(int index=0; index<commands.Length; index++){                commands[index].execute();            }        }        public void undo(){            for (int index = 0; index < commands.Length; index++){                commands[index].undo();            }        }    }    public class LightOnCommand : Command{        Light light;        public LightOnCommand(Light light){            this.light = light;        }        public void execute(){            light.On();        }        public void undo(){            light.Off();        }    }    public class LightOffCommand : Command{        Light light;        public LightOffCommand(Light light){            this.light = light;        }        public void execute(){            light.Off();        }        public void undo(){            light.On();        }    }    public class RemoteControl{        Command[] onCommands;        Command[] offCommands;        Command undoCommand;

            public RemoteControl(){            onCommands = new Command[7];            offCommands = new Command[7];

                //可以避免在每次调onButtonWasPushed时检测命令是否为空            Command noCommand = new NoCommand();            for (int index = 0; index < 7; index++){                onCommands[index] = noCommand;                offCommands[index] = noCommand;            }

                undoCommand = noCommand;        }        public void setCommand(int slot, Command onCommand, Command offCommand){            onCommands[slot] = onCommand;            offCommands[slot] = offCommand;        }        public void onButtonWasPushed(int slot){            onCommands[slot].execute();            undoCommand = onCommands[slot];        }        public void offButtonWasPushed(int slot){            offCommands[slot].execute();            undoCommand = offCommands[slot];        }        public void undoButtonWasPushed(){            undoCommand.undo();        }        public String toString(){            StringBuilder sb = new StringBuilder();            sb.Append("/n------ Remote Control -------/n");            for (int i = 0; i < onCommands.Length; i++){                sb.Append("[slot " + i + "] " + onCommands[i].GetType().Name                    + "    " + offCommands[i].GetType().Name + "/n");            }            return sb.ToString();        }    }

        class Program    {        static void Main(string[] args)        {            //管理一组命令对象,每个按钮都有一个命令对象。            //每次按下按钮,就调用相应的**ButtonWasPushed方法,间接调用EXECUTE方法            RemoteControl remoteControl = new RemoteControl();

                Light klight = new Light("1");            //利用Command接口,每个动作都被实现成一个简单得的命令对象。            //命令对象持有对一个厂商类的实例的引用,并实现EXECUTE方法            //这个方法会调用厂商类实例的一个或多个方法,完成特定的行为。            LightOnCommand lighton = new LightOnCommand(klight);            LightOffCommand lightoff = new LightOffCommand(klight);                        //1号卡槽,控制电灯开关            remoteControl.setCommand(1, lighton, lightoff);            remoteControl.onButtonWasPushed(1);            remoteControl.offButtonWasPushed(1);            remoteControl.undoButtonWasPushed();

                Command[] partyOn = { lighton};            Command[] partyOff = { lightoff };

                MacroCommand partyOnCmd = new MacroCommand(partyOn);            MacroCommand partyOffCmd = new MacroCommand(partyOff);

                //0号卡槽,控制所有设备的开关            remoteControl.setCommand(0, partyOnCmd, partyOffCmd);            remoteControl.onButtonWasPushed(0);            remoteControl.offButtonWasPushed(0);        }    }

    最新回复(0)