2.4 别忘了撤销
重新设计Command接口
public interface Command {
public void execute();
public void undo();
}
重新设计命令对象
public class LightOnCommand implements Command {
Light light;
int level;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
level = light.getLevel();
light.on();
}
public void undo() {
light.dim(level);
}
}
重新设计遥控器
public class RemoteControlWithUndo {
Command[] onCommands;
Command[] offCommands;
Command undoCommand;
public RemoteControlWithUndo() {
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;
}
//初始化的时候,并没有所谓的“前一个命令”,所以将它设置为NoCommand对象。
undoCommand = noCommand;
}
public void setCommand(int slot, Command onCommand, Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
public void onButtonWasPushed(int slot) {
onCommands[slot].execute();
/*
* 当按下按钮,我们取得这个命令,并优先执行它然后将它记录在nudoConmmand实例变量中。
* 不管是开或者关命令,我们的处理方法都是一样的。
*/
undoCommand = onCommands[slot];
}
public void offButtonWasPushed(int slot) {
offCommands[slot].execute();
undoCommand = offCommands[slot];
}
public void undoButtonWasPushed() {
//当按下撤销按钮,我们调用undoConmmand实例变量的Undo()方法,就可以倒转前一个命令。
undoCommand.undo();
}
public String toString() {
StringBuffer stringBuff = new StringBuffer();
stringBuff.append("\n------ Remote Control -------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
stringBuff.append("[undo] " + undoCommand.getClass().getName() + "\n");
return stringBuff.toString();
}
}
2.5 宏命令
public class MacroCommand implements Command {
Command[] commands;
public MacroCommand(Command[] commands) {
this.commands = commands;
}
//当这个宏命令被遥控器执行时,就会一次性执行数组里的每个命令
public void execute() {
for (int i = 0; i < commands.length; i++) {
commands[i].execute();
}
}
public void undo() {
for (int i = commands.length -1; i >= 0; i--) {
commands[i].undo();
}
}
}
2.6 命令模式的高级用途
队列请求和日志请求,关于这两个高级用途实例请 阅读其他材料,本书中只略微带过,不过这才是命令模式在实际应用中大展拳脚的地方,后面有机会再深入研究。
3 本章小结
玩过游戏的朋友肯定对宏这个东西不陌生,君不见wower必备的焦点宏,喊话宏,其实都是由一个个命令组成。命令模式在实际项目中的运用也是较多,各位coder有哪些实际经历呢?