美文网首页
理解命令模式

理解命令模式

作者: 梦的飞翔_862e | 来源:发表于2018-11-22 11:46 被阅读0次
    概念理解

    一个命令有命令的发出者和执行者,命令模式的主要目的是将这两者主体解耦。简单理解,发出的命令(不管是什么)是一个对象,对象中仅有做和不做两个方法。命令如何执行,有具体的命令实现对象调用命令接收者来具体执行。

    需求描述

    遥控器需要控制家中电灯的开关,以及冰箱的开关和设置温度。

    设计一:直接方式

    从直接实现的结构可以看出,发出命令者和执行命令者存在着紧耦合,这种结构不利于扩展。

    public class Fridge {
        private int temperature=10;
    
        public void on() {
            System.out.println("fridge is on ");
        }
    
        public void off() {
            System.out.println("fridge is  off");
        }
    
        public void temperatureUp() {
            this.temperature++;
            System.out.println(" up temperature:" + temperature + " is set");
        }
    
        public void temperatureDown() {
            this.temperature--;
            System.out.println(" down temperature:" + temperature + " is set");
        }
    }
    
    public class Light {
    
        public Light() {
        }
    
        public void on() {
            System.out.println("light is on ");
        }
    
        public void off() {
            System.out.println("light is off");
        }
    
    }
    
    public class Controller {
        private Light light = new Light();
        private Fridge fridge = new Fridge();
    
        public void invoke(int slot) {
            switch (slot) {
                case 1:
                    light.on();
                case 2:
                    light.off();
                case 3:
                    fridge.on();
                case 4:
                    fridge.off();
                case 5:
                    fridge.temperatureUp();
                case 6:
                    fridge.temperatureDown();
                default:
                    break;
            }
        }
    }
    

    命令模式的主要目的是加入中间层,命令对象,将命令发出者和执行者解耦。

    设计二:命令模式

    命令模式实际上就是在命令发出者和接受者之间加入了中间层——命令对象。



    挑选几个代码实例

    public interface Commander {
        void execute();
        void undo();
    }
    
    public class LightOnCommander implements Commander {
        private Light light;
    
        public LightOnCommander() {
            this.light = new Light();
        }
    
        @Override
        public void execute() {
            light.on();
    
        }
    
        @Override
        public void undo() {
            light.off();
    
        }
    }
    
    public class LightOffCommander implements  Commander{
        private Light light;
    
        public LightOffCommander(){
            this.light = new Light();
        }
    
        @Override
        public void execute() {
            light.off();
    
        }
    
        @Override
        public void undo() {
            light.on();
    
        }
    }
    
    public class ControlPannel {
        private int slot;
        private Commander[] onCommanders;
        private Commander[] offCommanders = new Commander[5];
    
        private Deque<Commander> stack;
    
        public ControlPannel() {
            onCommanders = new Commander[5];
            offCommanders = new Commander[5];
            Commander noCommander = new NoCommander();
            for (int i = 0; i < 5; i++) {
                onCommanders[i] = noCommander;
                offCommanders[i] = noCommander;
            }
            stack = new ArrayDeque<Commander>();
        }
    
        public void setCommanders(Commander onCommande, Commander offCommander, int slot) {
            onCommanders[slot] = onCommande;
            offCommanders[slot] = offCommander;
        }
    
        public void onButton(int slot) {
            onCommanders[slot].execute();
            stack.push(onCommanders[slot]);
        }
    
        public void offButton(int slot) {
            offCommanders[slot].execute();
            stack.push(offCommanders[slot]);
        }
    
        public void undoCommander() {
            stack.pop().undo();
        }
    }
    
    public class TestApp {
    
        public static void main(String[] args) {
            ControlPannel panel = initPanel();
            panel.onButton(1);
            panel.onButton(2);
            panel.undoCommander();
            panel.undoCommander();
        }
    
        public static ControlPannel initPanel() {
            ControlPannel pannel = new ControlPannel();
            pannel.setCommanders(new LightOnCommander(), new LightOffCommander(), 0);
            pannel.setCommanders(new FridgeOnCommander(), new FridgeOffCommander(), 1);
            pannel.setCommanders(new FridgeTmeperatureOnCommander(), new FrigdeTemperatureDownCommander(), 2);
            return pannel;
        }
    }
    
    注意点

    优点:命令模式的主要目的是解耦,层次分明,各司其职,方便扩展
    缺点:命令模式因为其层次结构的存在,如果存在多个命令,则会造成命令类过于庞大。

    具体代码实例参见https://github.com/jxl198/designPattern/tree/master/commander

    相关文章

      网友评论

          本文标题:理解命令模式

          本文链接:https://www.haomeiwen.com/subject/dnbkqqtx.html