zoukankan      html  css  js  c++  java
  • 23种设计模式之命令模式

    遥控器案例,控制灯开或关,音响音量大小,设置CD

    1、把命令封装成接口,不同设备继承接口实现功能;

    如上图,灯的开、关和音响开、关、调音量、设置CD功能类定义好,其相应功能的执行命令封装成接口,Control通过命令接口的方法实现对应功能; 

    public class Light {
    
        String loc="";//灯位置,如卧室,客厅
    
        public Light(String loc){
            this.loc=loc;
        }
    
        public void on(){
            System.out.println(loc+" On");
        }
    
        public void off(){
            System.out.println(loc+" Off");
        }
    
    }
    Light 灯功能类
    public class Stereo {
    
        static int volume=0;
    
        public void on(){
            System.out.println("Stereo On");
        }
    
        public void off(){
            System.out.println("Stereo Off");
        }
    
        public void setCD(){
            System.out.println("Stereo setCD");
        }
    
        public void setVol(int vol){
            this.volume=vol;
            System.out.println("Stereo volume="+volume);
        }
    
        public int getVol(){
            return volume;
        }
    
        public void start(){
            System.out.println("Stereo Start");
        }
    
    }
    Stereo 音响功能类
    public interface Command {
    
        public void execute();
    
        public void undo();
    
    }
    Command 命令接口

    单独的功能,如灯的开、关和音响的开、关、调大音量、调小音量,实现命令接口

    public class LightOnCommand implements Command {
    
        private Light light;
    
        public LightOnCommand(Light light) {
            this.light = light;
        }
    
        public void execute() {
            light.on();
        }
    
        public void undo() {
            light.off();
        }
    }
    LightOnCommand implements Command开灯功能
    public class LightOffCommand implements Command {
    
        private Light light;
    
        public LightOffCommand(Light light) {
            this.light = light;
        }
    
        public void execute() {
            light.off();
        }
    
        public void undo() {
            light.on();
        }
    }
    LightOffCommand implements Command关灯功能
    public class StereoOnCommand implements Command {
    
        private Stereo stereo;
    
        public StereoOnCommand(Stereo stereo) {
            this.stereo = stereo;
        }
    
        public void execute() {
            //可以多个命令同时执行
            stereo.on();
            stereo.setCD();
        }
    
        public void undo() {
            stereo.off();
        }
    }
    StereoOnCommand implements Command开音响功能
    public class StereoOffCommand implements Command {
    
        private Stereo stereo;
    
        public StereoOffCommand(Stereo stereo) {
            this.stereo = stereo;
        }
    
        public void execute() {
            stereo.off();
        }
    
        public void undo() {
            stereo.on();
        }
    }
    StereoOffCommand implements Command关音响功能
    public class StereoAddVolCommand implements Command {
    
        private Stereo stereo;
    
        public StereoAddVolCommand(Stereo stereo) {
            this.stereo = stereo;
        }
    
        public void execute() {
            int vol = stereo.getVol();
            if (vol < 11) {
                stereo.setVol(++vol);
            }
        }
    
        public void undo() {
            int vol = stereo.getVol();
            if (vol > 0) {
                stereo.setVol(--vol);
            }
        }
    }
    StereoAddVolCommand implements Command调大音量功能
    public class StereoSubVolCommand implements Command {
    
        private Stereo stereo;
    
        public StereoSubVolCommand(Stereo stereo) {
            this.stereo = stereo;
        }
    
        public void execute() {
            int vol = stereo.getVol();
            if (vol > 0) {
                stereo.setVol(--vol);
            }
        }
    
        public void undo() {
            int vol = stereo.getVol();
            if (vol < 11) {
                stereo.setVol(++vol);
            }
        }
    }
    StereoSubVolCommand implements Command调小音量功能

    NoCommand类,用来初始化命令控制器上按钮,内部实现命令接口,但不执行功能,就类似按按钮不起作用

    public class NoCommand implements Command {
        public void execute() {
    
        }
    
        public void undo() {
    
        }
    }
    NoCommand implements Command

    遥控器接口,遥控器通过控制每一排的开、关按钮来让相应的功能命令执行

    public interface Control {
    
        //slot位置,即打开或关闭哪排按钮
    
        void onButton(int slot);
    
        void offButton(int slot);
    
        void undoButton();
    
        void setCommand(int slot, Command onCommand, Command offCommand);
    
    }
    Control 遥控器接口
    public class CommandModeControl implements Control {
    
        private Command[] onCommands;
        private Command[] offCommands;
        private Stack<Command> stack=new Stack<Command>();
    
        public CommandModeControl() {
            onCommands = new Command[5];
            offCommands = new Command[5];
    
            Command noCommand = new NoCommand();
    
            for (int i = 0; i < onCommands.length; i++) {
                onCommands[i] = noCommand;
                offCommands[i] = noCommand;
            }
        }
    
        public void setCommand(int slot, Command onCommand, Command offCommand) {
            onCommands[slot] = onCommand;
            offCommands[slot] = offCommand;
        }
    
        public void onButton(int slot) {
            onCommands[slot].execute();
            stack.push(onCommands[slot]);
        }
    
        public void offButton(int slot) {
            offCommands[slot].execute();
            stack.push(offCommands[slot]);
        }
    
        public void undoButton() {
            stack.pop().undo();
        }
    }
    CommandModeControl implements Control遥控器接口实现,初始化设置每排开、关按钮命令为nocommand,setCommand方法设置某排控制灯或音响功能,其中onCommand和offCommand数组表示两排开关按钮

     下面再添加一同时控制多个功能的命令

    public class MarcoCommand implements Command {
    
        private Command[] commands;
    
        public MarcoCommand(Command[] 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();
            }
        }
    }
    MarcoCommand implements Command通过传入命令数组,数组中的命令同时执行

    遥控器操作设备,也就是Control中的onButton、offButton调用Command的execute方法,undoButton执行Command的undo方法

    设备功能实现Command接口,各自实现不同,而Command接口对外暴露的只有相同的方法

    public class ControlTest {
    
        public static void main(String[] args){
            Control control=new CommandModeControl();
            Light bedroomLight=new Light("BedRoom");
            Light kitchLight=new Light("Kitch");
            Stereo stereo=new Stereo();
    
            Command bedroomLightOn=new LightOnCommand(bedroomLight);
            Command bedroomLightOff=new LightOffCommand(bedroomLight);
            Command kitchLightOn=new LightOnCommand(kitchLight);
            Command kitchLightOff=new LightOffCommand(kitchLight);
    
            //同时开、关两个灯
            Command[] onCommands={bedroomLightOn,kitchLightOn};
            Command[] offCommands={bedroomLightOff,kitchLightOff};
            Command marcoCommandOn=new MarcoCommand(onCommands);
            Command marcoCommandOff=new MarcoCommand(offCommands);
    
            Command stereoOn=new StereoOnCommand(stereo);
            Command stereoOff=new StereoOffCommand(stereo);
            Command stereoAddVol=new StereoAddVolCommand(stereo);
            Command stereoSubVol=new StereoSubVolCommand(stereo);
    
            control.setCommand(0,bedroomLightOn,bedroomLightOff);
            control.setCommand(1,kitchLightOn,kitchLightOff);
            control.setCommand(2,stereoOn,stereoOff);
            control.setCommand(3,stereoAddVol,stereoSubVol);
            control.setCommand(4,marcoCommandOn,marcoCommandOff);
    
            control.onButton(0);
            control.offButton(0);
            control.onButton(1);
            control.offButton(1);
            control.onButton(2);
            control.offButton(2);
            control.onButton(3);
            control.offButton(3);
            System.out.println("~~~~~~~~~~~~~");
            control.onButton(4);
            control.offButton(4);
        }
    
    }
    测试代码

    解耦后,设备升级或添加新设备,都不会影响其他设备代码

  • 相关阅读:
    秋季总结
    PTA第一个编程题总结
    秋季学习总结
    人生路上对我影响最大的三位老师
    自我介绍
    真实的我——自我介绍
    学习总结
    寒假编程总结三
    寒假编程总结二
    寒假编程总结一
  • 原文地址:https://www.cnblogs.com/hujiapeng/p/8145677.html
Copyright © 2011-2022 走看看