命令模式
行为型模式
命令模式(Command Pattern)是一种数据驱动的设计模式,申请以命令的模式包裹在对象中,并传给调用对象。调用对象寻找能够解决该命令的适合的对象,并把该命令传给相应的对象,该对象执行命令。
介绍
用意: 将一个申请封装成一个对象,从而使您能够用不同的申请对客户进行参数化。
次要解决: 在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比方须要对行为进行记录、撤销或重做、事务等解决时,这种无奈抵挡变动的紧耦合的设计就不太适合。
何时应用: 在某些场合,比方要对行为进行"记录、撤销/重做、事务"等解决,这种无奈抵挡变动的紧耦合是不适合的。在这种状况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为形象为对象,能够实现二者之间的松耦合。
如何解决: 通过调用者调用接受者执行命令,程序:调用者→接受者→命令。
要害代码: 定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 应用命令对象的入口
具体实现
咱们买了一套智能家电,有照明灯,风扇,冰箱,电视等等,咱们只有在手机上安装app就能够管制这些家电,但咱们不想针对每一种家电都装置一个app来别离管制,咱们心愿一个app就能够管制全副的家电。
在该案例中咱们采纳遥控器模式来展示命令模式。
第一步:创立命令接口
public interface Command { //执行命令 void execute(); //撤销命令 void undo();}
第二步:创立电灯和电视机命令执行对象
public class LightReceiver { public void on(){ System.out.println("电灯关上了..."); } public void off(){ System.out.println("电灯敞开了..."); }}
public class TVReceiver { public void on() { System.out.println("电视机关上了..."); } public void off() { System.out.println("电视机敞开了..."); }}
第三步:创立电灯和电视机操作实现类
public class LightOnCommand implements Command { //聚合LightReceiver private LightReceiver lightReceiver; public LightOnCommand(LightReceiver lightReceiver) { this.lightReceiver = lightReceiver; } @Override public void execute() { System.out.println("调用接受者的办法..."); lightReceiver.on(); } @Override public void undo() { System.out.println("调用接受者的办法..."); lightReceiver.off(); }}
public class LightOffCommand implements Command { //聚合LightReceiver private LightReceiver lightReceiver; public LightOffCommand(LightReceiver lightReceiver) { this.lightReceiver = lightReceiver; } @Override public void execute() { System.out.println("调用接受者的办法..."); lightReceiver.off(); } @Override public void undo() { System.out.println("调用接受者的办法..."); lightReceiver.on(); }}
public class TVOffCommand implements Command { //聚合TVReceiver private TVReceiver tvReceiver; public TVOffCommand(TVReceiver tvReceiver) { this.tvReceiver = tvReceiver; } @Override public void execute() { System.out.println("调用接受者的办法..."); tvReceiver.off(); } @Override public void undo() { System.out.println("调用接受者的办法..."); tvReceiver.on(); }}
public class TVOnCommand implements Command { //聚合TV private TVReceiver tvReceiver; public TVOnCommand(TVReceiver tvReceiver) { this.tvReceiver = tvReceiver; } @Override public void execute() { System.out.println("调用接受者的办法..."); tvReceiver.on(); } @Override public void undo() { System.out.println("调用接受者的办法..."); tvReceiver.off(); }}
/** * 没有任何命令,即空执行:用于初始化每个按钮,当调用空命令时,对象什么都不做 */public class EmptyCommand implements Command{ @Override public void execute() { } @Override public void undo() { }}
第四步:创立遥控器
public class RemoteController { //开关命令数组 Command[] onCommands; Command[] offCommands; //执行撤销命令 Command undoCommand; public RemoteController() { onCommands = new Command[5]; offCommands = new Command[5]; for (int i = 0; i < 5; i++) { onCommands[i] = new EmptyCommand(); offCommands[i] = new EmptyCommand(); } } //给咱们的按钮设置你须要的命令 public void setCommand(int no, Command onCommand, Command offCommand) { onCommands[no] = onCommand; offCommands[no] = offCommand; } //按下开按钮 public void onButtonWasPushed(int no) { //找到你按下的开的按钮,并调用对应办法. onCommands[no].execute(); //记录以后按钮,用于撤销. undoCommand = onCommands[no]; } //按下关按钮 public void offButtonWasPushed(int no) { //找到你按下的关的按钮,并调用对应办法. offCommands[no].execute(); //记录以后按钮,用于撤销. undoCommand = offCommands[no]; } //按下撤销按钮 public void undoButtonWasPushed(int no) { undoCommand.undo(); }}
第五步:创立测试类
public class Client { public static void main(String[] args) { //应用命令设计模式,实现通过遥控器,对电灯的操作 //创立电灯对象(接受者) LightReceiver lightReceiver = new LightReceiver(); //创立电灯相干的开关命令 LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver); LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver); //须要一个遥控器来管制 RemoteController remoteController = new RemoteController(); //给咱们的遥控器设置命令,比方 no = 0 是电灯的开和关操作. remoteController.setCommand(0, lightOnCommand, lightOffCommand); System.out.println("---------按下电灯的开按钮--------"); remoteController.onButtonWasPushed(0); System.out.println("---------按下电灯的关按钮--------"); remoteController.offButtonWasPushed(0); System.out.println("---------按下电灯的撤销按钮--------"); remoteController.undoButtonWasPushed(0); //创立电视机对象(接受者) TVReceiver tvReceiver = new TVReceiver(); //创立电视机相干的开关命令 TVOnCommand tvOnCommand = new TVOnCommand(tvReceiver); TVOffCommand tvOffCommand = new TVOffCommand(tvReceiver); //须要一个遥控器来管制 //给咱们的遥控器设置命令,比方 no = 1 是电视机的开和关操作. remoteController.setCommand(1, tvOnCommand, tvOffCommand); System.out.println("---------按下电视机的开按钮--------"); remoteController.onButtonWasPushed(1); System.out.println("---------按下电视机的关按钮--------"); remoteController.offButtonWasPushed(1); System.out.println("---------按下电视机的撤销按钮--------"); remoteController.undoButtonWasPushed(1); }}
运行如下:
---------按下电灯的开按钮--------调用接受者的办法...电灯关上了...---------按下电灯的关按钮--------调用接受者的办法...电灯敞开了...---------按下电灯的撤销按钮--------调用接受者的办法...电灯关上了...---------按下电视机的开按钮--------调用接受者的办法...电视机关上了...---------按下电视机的关按钮--------调用接受者的办法...电视机敞开了...---------按下电视机的撤销按钮--------调用接受者的办法...电视机关上了...
长处:
1、升高了零碎耦合度。 2、新的命令能够很容易增加到零碎中去。
毛病:
应用命令模式可能会导致某些零碎有过多的具体命令类。