概述:
命令模式:将一组行为抽象成对象,实现“行为请求者”和“行为执行者”之间松耦合。
按照《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