命令模式(command pattern) 撤销(undo) 详解
本文地址: http://blog.csdn.net/caroline_wendy
参考命令模式: http://blog.csdn.net/caroline_wendy/article/details/31379977
命令模式可以用于执行撤销(undo)操作.
具体方法:
1. 对象类中需要保存状态, 如level.
package command;
public class CeilingFan {
String location = "";
int level;
public static final int HIGH = 3;
public static final int MEDIUM = 2;
public static final int LOW = 1;
public static final int OFF = 0;
public CeilingFan(String location) {
this.location = location;
}
public void high() {
// turns the ceiling fan on to high
level = HIGH;
System.out.println(location + " ceiling fan is on high");
}
public void medium() {
// turns the ceiling fan on to medium
level = MEDIUM;
System.out.println(location + " ceiling fan is on medium");
}
public void low() {
// turns the ceiling fan on to low
level = LOW;
System.out.println(location + " ceiling fan is on low");
}
public void off() {
// turns the ceiling fan off
level = OFF;
System.out.println(location + " ceiling fan is off");
}
public int getSpeed() {
return level;
}
}
2. 命令接口, 包含撤销(undo)操作, 即根据传入对象的状态参数, 判断具体的撤销动作.
/**
* @time 2014年6月9日
*/
package command;
/**
* @author C.L.Wang
*
*/
public interface Command {
public void execute();
public void undo(); //撤销
}
3. 具体命令(Concrete Command)类需要实现, 撤销操作, 根据不同状态, 执行不同的撤销操作.
/**
* @time 2014年6月16日
*/
package command;
/**
* @author C.L.Wang
*
*/
public class CeilingFanHighCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed;
public CeilingFanHighCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}
/* (non-Javadoc)
* @see command.Command#execute()
*/
@Override
public void execute() {
// TODO Auto-generated method stub
prevSpeed = ceilingFan.getSpeed();
ceilingFan.high();
}
/* (non-Javadoc)
* @see command.Command#undo()
*/
@Override
public void undo() {
// TODO Auto-generated method stub
if (prevSpeed == CeilingFan.HIGH) {
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM) {
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW) {
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF) {
ceilingFan.off();
}
}
}
package command;
public class CeilingFanMediumCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed;
public CeilingFanMediumCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}
public void execute() {
prevSpeed = ceilingFan.getSpeed();
ceilingFan.medium();
}
public void undo() {
if (prevSpeed == CeilingFan.HIGH) {
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM) {
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW) {
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF) {
ceilingFan.off();
}
}
}
package command;
public class CeilingFanLowCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed;
public CeilingFanLowCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}
public void execute() {
prevSpeed = ceilingFan.getSpeed();
ceilingFan.low();
}
public void undo() {
if (prevSpeed == CeilingFan.HIGH) {
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM) {
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW) {
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF) {
ceilingFan.off();
}
}
}
package command;
public class CeilingFanOffCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed;
public CeilingFanOffCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}
public void execute() {
prevSpeed = ceilingFan.getSpeed();
ceilingFan.off();
}
public void undo() {
if (prevSpeed == CeilingFan.HIGH) {
ceilingFan.high();
} else if (prevSpeed == CeilingFan.MEDIUM) {
ceilingFan.medium();
} else if (prevSpeed == CeilingFan.LOW) {
ceilingFan.low();
} else if (prevSpeed == CeilingFan.OFF) {
ceilingFan.off();
}
}
}
4. 接受者(Receiver)类实现撤销(undo)操作, 即在调用命令时, 保留命令, 执行撤销(undo)操作时, 调用保留的命令.
/**
* @time 2014年6月16日
*/
package command;
/**
* @author C.L.Wang
*
*/
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 = noCommand;
}
public void setCommand (int slot, Command onCommand, Command offCommand) {
this.onCommands[slot] = onCommand;
this.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();
}
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("\n------ Remote Control ------\n");
for (int i=0; i<onCommands.length; ++i) {
stringBuffer.append("[slot " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
return stringBuffer.toString();
}
}
5. 测试类, 调用不同的命令, 保存不同的状态, 执行撤销操作.
/**
* @time 2014年6月16日
*/
package command;
import javax.crypto.spec.IvParameterSpec;
/**
* @author C.L.Wang
*
*/
public class RemoteLoader {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
RemoteControl remoteControl = new RemoteControl();
Light livingRoomLight = new Light("Living Room");
Light kitchenLight = new Light("Kitchen");
CeilingFan ceilingFan = new CeilingFan("Living Room");
GarageDoor garageDoor = new GarageDoor("");
Stereo stereo = new Stereo("Living Room");
LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight);
LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight);
LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight);
LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight);
CeilingFanHighCommand ceilingFanHigh = new CeilingFanHighCommand(ceilingFan);
CeilingFanMediumCommand ceilingFanMedium = new CeilingFanMediumCommand(ceilingFan);
CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan);
GarageDoorOnCommand garageDoorOn = new GarageDoorOnCommand(garageDoor);
GarageDoorOffCommand garageDoorOff = new GarageDoorOffCommand(garageDoor);
StereoOnWithCDCommand stereoOnWithCD = new StereoOnWithCDCommand(stereo);
StereoOffCommand stereoOffCommand = new StereoOffCommand(stereo);
remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff); //设这遥控器
remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff);
remoteControl.setCommand(2, ceilingFanHigh, ceilingFanOff);
remoteControl.setCommand(3, ceilingFanMedium, ceilingFanOff);
remoteControl.setCommand(4, stereoOnWithCD, stereoOffCommand);
remoteControl.onButtonWasPushed(2); //高速
remoteControl.offButtonWasPushed(2); //关闭高速
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed(); //退回高速
System.out.println();
remoteControl.onButtonWasPushed(3); //中速
System.out.println(remoteControl);
remoteControl.undoButtonWasPushed(); //高速
}
}
6. 输出:
Living Room ceiling fan is on high
Living Room ceiling fan is off
------ Remote Control ------
[slot 0] command.LightOnCommand command.LightOffCommand
[slot 1] command.LightOnCommand command.LightOffCommand
[slot 2] command.CeilingFanHighCommand command.CeilingFanOffCommand
[slot 3] command.CeilingFanMediumCommand command.CeilingFanOffCommand
[slot 4] command.StereoOnWithCDCommand command.StereoOffCommand
[slot 5] command.NoCommand command.NoCommand
[slot 6] command.NoCommand command.NoCommand
Living Room ceiling fan is on high
Living Room ceiling fan is on medium
------ Remote Control ------
[slot 0] command.LightOnCommand command.LightOffCommand
[slot 1] command.LightOnCommand command.LightOffCommand
[slot 2] command.CeilingFanHighCommand command.CeilingFanOffCommand
[slot 3] command.CeilingFanMediumCommand command.CeilingFanOffCommand
[slot 4] command.StereoOnWithCDCommand command.StereoOffCommand
[slot 5] command.NoCommand command.NoCommand
[slot 6] command.NoCommand command.NoCommand
Living Room ceiling fan is on high
其余代码下载: http://download.csdn.net/detail/u012515223/7507147