本文是阅读《Head First 设计模式》的学习记录。详细内容可以自行阅读书本
命令模式
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
举例
设计遥控器,分别装有7组“开”与“关”按钮来控制多个设备,还需要支持整体的撤销功能。
1.首先,我们需要实现命令的接口
public interface Command {
public void execute();
public void undo();
}
2.分别实现开灯、关灯、开关电风扇等命令
public class LightOffCommand implements Command{
Light light;
//传入对象,以便后续方法中调用
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
public class CeilingFanOffCommand implements Command {
Fan fan;
public CeilingFanOffCommand(Fan fan) {
this.fan = fan;
}
@Override
public void execute() {
fan.off();
}
@Override
public void undo() {
fan.on();
}
}
3.如果不满足单一命令调用,我们完全可以自定义命令
public class MacroCommand implements Command{
public Command[] commands;
//自定义命令集合
public MacroCommand(Command[] commands) {
this.commands = commands;
}
//调用所有命令的执行
@Override
public void execute() {
for (Command command : commands) {
command.execute();
}
}
@Override
public void undo() {
for (Command command : commands) {
command.undo();
}
}
}
4.实现遥控器
public class RemoteControl {
//记录所有命令操作
Command[] onCommands;
Command[] offCommands;
//记录最近一次操作,方法撤销
Command undoCommand;
public RemoteControl() {
onCommands = new Command[7];
offCommands = new Command[7];
Command noCommand = new NoCommand();
for (int i = 0; i < 7; i++) {
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
undoCommand = new NoCommand();
}
public void setCommands(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
undoCommand = onCommands[slot];
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void undoButtonWasPushed() {
undoCommand.undo();
}
}
5.测试
public class Test {
public static void main(String[] args) {
RemoteControl remoteControl = new RemoteControl();
Light livingLight = new LivingRoomLight();
Light kitchenLight = new KitchenLight();
Fan fan = new Fan();
//创建命令对象
LightOnCommand livingLightOn = new LightOnCommand(livingLight);
LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
LightOffCommand livingLightOff = new LightOffCommand(livingLight);
LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);
CeilingFanOnCommand fanOnCommand = new CeilingFanOnCommand(fan);
CeilingFanOffCommand fanOffCommand = new CeilingFanOffCommand(fan);
//将命令组合成一个
Command[] partyOn = {livingLightOn, kitchenLightOn, fanOnCommand};
Command[] partyOff = {livingLightOff, kitchenLightOff, fanOffCommand};
MacroCommand macroOnCommand = new MacroCommand(partyOn);
MacroCommand macroOffCommand = new MacroCommand(partyOff);
//将命令加载到控制中
remoteControl.setCommands(0, livingLightOn, livingLightOff);
remoteControl.setCommands(1, kitchenLightOn, kitchenLightOff);
remoteControl.setCommands(2, fanOnCommand, fanOffCommand);
remoteControl.setCommands(3, macroOnCommand, macroOffCommand);
//测试
remoteControl.offButtonWasPushed(0);
remoteControl.onButtonWasPushed(1);
remoteControl.undoButtonWasPushed();
remoteControl.offButtonWasPushed(1);
remoteControl.onButtonWasPushed(2);
}
}