命令模式

概述:

命令模式:将一组行为抽象成对象,实现“行为请求者”和“行为执行者”之间松耦合。

 

按照《Head First 设计模式》中命令模式章节中的例子。一个遥控器,分为左右两排按钮,左边开,右边关,最后一个按钮为撤销上一次的操作。当我想要开灯的时候,就要按下左边第一个按钮,关灯则要按右边第一个按钮。

此时,我们可以把 开灯、关灯 这些命令(行为),抽象成一个个对象。使行为请求者(我)持有 这些 命令对象,当我想要开灯,就调用“开灯” 这个对象,这个对象就会帮助我们开灯,而我不需要关注它是怎么帮我开灯的。

命令模式

 

关系图:

命令模式

 

具体的代码实现(以“开灯”为例): 

public interface Command {  //这是抽象的命令的接口
    void  execute(); //执行
    void  undo();  //撤销
}

  

public class LightOnCommand implements Command { //开灯命令 具体的实现类
    Light light; //行为执行者
    public LightCommand(Light light){
        this.light = light;
    }
    @Override
    public void execute() {
        light.lightOn(); //开灯
    }

    public void undo(){
        light.lightOff(); //撤销开灯的操作 -- 关灯。。。
    }
}

  

public class Controller {  //行为请求者
Command command; //持有命令对象 public void setCommand(Command command){ this.command = command; // } public void buttonOnPress(){ command.execute(); //调用命令对象的execute() } public void back(){ command.undo(); //调用命令对象的undo() } }

  

public class Light { //行为执行者 

    public void lightOn(){
        System.out.println("light on");
    }

    public void lightOff(){
        System.out.println("light off");
    }
}

  

接下来就是测试代码:

public class Test {
    public static void main(String[] args) {
        Controller controller = new Controller(); 

        Light light = new Light();
        LightOnCommand lightCommand = new LightOnCommand(light); //传入行为执行者

        controller.setCommand(lightCommand);  //传入命令对象
        controller.buttonOnPress(); //开灯
        
        controller.back(); //撤销开灯操作
    }
}

  控制台输出如下:

light on
light off

  

这样,我就可以通过 LightOnCommand 来开灯了!

如果想要打开电视,也是同理 , 创建 TelevisionCommond ,实现 Commond接口的方法 即可。

 

 

 

关于宏命令:假设,此时添加了一个按钮,要求一键 开灯、开电视。那么我们可以把 开灯、开电视的命令对象 都交给这个新的命令。

public class OpenAllCommand implements Command {
    Command[] commands;   //可以用数组的形式保存这些命令对象
    public OpenAllCommand(Command[] commands){
        this.commands = commands;
    }

    @Override
    public void execute() {
        for (int i = 0;i<commands.length;i++) {
            commands[i].execute(); 
        }
    }

    @Override
    public void undo() {
        for (int i = 0;i<commands.length;i++) {
            commands[i].undo();
        }
    }
}

  

测试:

public class Test {
    public static void main(String[] args) {
        Controller controller = new Controller();

        Light light = new Light();
        LightOnCommand lightCommand = new LightOnCommand(light);

        TelevisionCommond televisionCommond = new TelevisionCommond(new Television());

        Command[] commands = new Command[]{lightCommand,televisionCommond};
        OpenAllCommand openAllCommand = new OpenAllCommand(commands);
controller.setCommand(openAllCommand); //使行为执行者持有命令对象 controller.buttonOnPress(); } }

控制台输出:

light on
Turn on the TV

  

OK!

总结:

  命令模式实现了 行为请求者和行为执行者之间的解耦,还可以在执行的时候动态的添加新的命令。

  但是,有可能会创建非常多的命令对象。。

 

PS:有错误之处,还请指出,谢谢!!! 自学不久,经验不足,还请多多包涵,感谢您的观看! 

 

2019-12-14    16:44:45

上一篇:h5+app设置手机状态栏颜色


下一篇:LED Holiday Light -Picking LED Christmas Lights, 4 Things