命令模式
命令模式:主要作用还是用于解耦。
命令发布者和执行者之间的解耦,命令发起者不用关心谁去执行,只要把命令发给中间人,中间人把命令发给执行者。
主要解决: 在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
举例: 遥控器中有开关各种电器的命令,如果使用命令模式,那么流程就应该是 遥控器发出命令==》命令中间者==》电器(电灯或电视)。命令发出后,还可以支持撤销命令;
代码类图:
RemoteController: 命令的发起者(遥控器),这个类会聚合命令中间者(Command);
Command: 命令中间者,接口类,起到转发命令的作用,也就是这个类把命令的发起者和命令的执行者做到了解耦。该接口中只定义了执行命令的的方法和撤销命令的方法;
LightOnCommand: 中间者的实现类,该类实现了开电灯,并实现了撤销时执行关电灯的命令。该实现类必须聚合真正的命令执行者。
LightOffCommand: 中间者的实现类,该类实现了关电灯,并实现了撤销时执行关电灯的命令。该实现类必须聚合真正的命令执行者。
LightReceiver: 命令的真实执行者;
代码:
/**
* 命令接口--中间者
*/
public interface Command {
//执行命令动作
void execute();
//撤销命令的动作
void undo();
}
/**
* 电灯命令的真正执行者
*/
public class LightReceiver {
public void on() {
System.out.println("开电灯。。。。");
}
public void off() {
System.out.println("关电灯。。。。");
}
}
/**
* 电灯 开命令执行的中间者
*/
public class LightOnCommand implements Command {
//聚合真正的命令执行者
LightReceiver lightReceiver;
public LightOnCommand(LightReceiver lightReceiver) {
this.lightReceiver = lightReceiver;
}
public void execute() {
lightReceiver.on();
}
public void undo() {
lightReceiver.off();
}
}
/**
* 电灯 关命令执行的中间者
*/
public class LightOffCommand implements Command {
//聚合真正的命令执行者
LightReceiver lightReceiver;
public LightOffCommand(LightReceiver lightReceiver) {
this.lightReceiver = lightReceiver;
}
public void execute() {
lightReceiver.off();
}
public void undo() {
lightReceiver.on();
}
}
/**
* 遥控器类,命令的发起者,会聚合命令中间者
*/
public class RemoteController {
//record 记录遥控器上各种电器的位置
Map<String, Integer> record = null;
{
record = new HashMap<String, Integer>(5);
record.put("电灯",0);
record.put("电视",1);
}
//下面的两个数组,用来存放遥控器的命令。因为遥控器上有多种电器的控制命令
Command[] onCommands = new Command[5];
Command[] offCommands = new Command[5];
//用于记录上一次的操作命令
Command unCommand;
/**
* 传入电器的命令
* @param type 电器的类型
* @param onCommand 电器的开命令
* @param offCommand 电器的关命令
*/
public void setCommands(String type, Command onCommand, Command offCommand) {
this.onCommands[record.get(type)] = onCommand;
this.offCommands[record.get(type)] = offCommand;
}
/**
* 执行开命令
* 传入电器的命令
* @param type 电器的类型
*/
public void executeOn(String type) {
Command onCommand = this.onCommands[record.get(type)];
onCommand.execute();
this.unCommand = onCommand;
}
/**
* 执行关命令
* 传入电器的命令
* @param type 电器的类型
*/
public void executeOff(String type) {
Command offCommand = this.offCommands[record.get(type)];
offCommand.execute();
this.unCommand = offCommand;
}
/**
* 撤销上次执行的命令
*/
public void revoke() {
this.unCommand.undo();
}
}
/**
* 测试
*/
public class Client {
public static void main(String[] args) {
RemoteController remoteController = new RemoteController();
LightReceiver lightReceiver = new LightReceiver();
remoteController.setCommands("电灯", new LightOnCommand(lightReceiver), new LightOffCommand(lightReceiver));
System.out.println("----------执行开始--------------");
remoteController.executeOn("电灯");
System.out.println("----------撤销命令--------------");
remoteController.revoke();
System.out.println("----------又执行开始--------------");
remoteController.executeOff("电灯");
System.out.println("----------又撤销命令--------------");
remoteController.revoke();
}
}