命令模式
行为型模式
命令模式(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、新的命令能够很容易增加到零碎中去。
毛病:
应用命令模式可能会导致某些零碎有过多的具体命令类。