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

本文深入浅出地介绍了设计模式中的命令模式,包括其基本概念、实现原理及应用场景。通过具体示例,展示了如何将请求封装为对象,从而实现解耦请求发送者与接收者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

深入浅出设计模式-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);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值