使用命令模式实现遥控器,遥控器上的不同按钮控制电灯的开关及亮度、天花板风扇的开关及转速等,支持撤销。
具体按钮:开灯/关灯按钮、暗光开/关按钮、风扇高速/中速/低速/关按钮、撤销按钮。
遥控器如下图所示:
遥控器担当请求者(或称为调用者)的角色,用RemoteControlWithUndo类实现,其内有Command[]类型的属性onCommands和offCommands表示对应的一组开关,Command类型的属性undoCommand记录最后执行的命令用于命令的撤销。遥控器上有7组开关按钮和一个撤销按钮。每个按钮对应一个具体命令,说明如下:
public interface Command { public void execute(); public void undo();//实现撤销 }
(1)Light电灯:
public class Light { String location; int level;//灯光的亮度 public Light(String location) { this.location = location; } public void on() { level = 100; System.out.println("Light is on"); } public void off() { level = 0; System.out.println("Light is off"); } //调整灯光的亮度 public void dim(int level) { this.level = level; if (level == 0) { off(); } else { System.out.println("Light is dimmed to " + level + "%"); } } //获取灯光的亮度 public int getLevel() { return level; } }
(2)CeilingFan风扇:
public class CeilingFan { public static final int HIGH = 3; public static final int MEDIUM = 2; public static final int LOW = 1; public static final int OFF = 0; String location;//例如卧室、客厅的风扇? int speed; public CeilingFan(String location) { this.location = location; speed = OFF; } public void high() { speed = HIGH; System.out.println(location + " ceiling fan is on high"); } public void medium() { speed = MEDIUM; System.out.println(location + " ceiling fan is on medium"); } public void low() { speed = LOW; System.out.println(location + " ceiling fan is on low"); } public void off() { speed = OFF; System.out.println(location + " ceiling fan is off"); } public int getSpeed() { return speed; } }
(1)NoCommand:空命令,创建遥控器时默认其持有的都是空命令(相比判断null更好),什么事也不做
public class NoCommand implements Command { public void execute() { } public void undo() { } }
public class LightOnCommand implements Command { Light light; int level;//level用于记录上次的灯光亮度 public LightOnCommand(Light light) { this.light = light; } public void execute() { level = light.getLevel(); light.on(); } public void undo() {//将灯光的亮度调到前一次的水平实现撤销 light.dim(level); } }
public class LightOffCommand implements Command { Light light; int level; public LightOffCommand(Light light) { this.light = light; } public void execute() { level = light.getLevel(); light.off(); } public void undo() { light.dim(level); } }
public class DimmerLightOnCommand implements Command { Light light; int prevLevel;//记录以前的灯光亮度,撤销操作时使用 public DimmerLightOnCommand(Light light) { this.light = light; } public void execute() { prevLevel = light.getLevel(); light.dim(75);//将灯光亮度调至75%实现暗光 } public void undo() { light.dim(prevLevel); } }
public class DimmerLightOffCommand implements Command { Light light; int prevLevel; public DimmerLightOffCommand(Light light) { this.light = light; prevLevel = 100; } public void execute() { prevLevel = light.getLevel(); light.off(); } public void undo() { light.dim(prevLevel); } }
public class CeilingFanHighCommand implements Command { CeilingFan ceilingFan; int prevSpeed;//记录以前的转速,用于撤销操作(0时表示以前的状态是:关) public CeilingFanHighCommand(CeilingFan ceilingFan) { this.ceilingFan = ceilingFan; } public void execute() { prevSpeed = ceilingFan.getSpeed(); ceilingFan.high(); } 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(); } } }
public class CeilingFanMediumCommand implements Command { CeilingFan ceilingFan; int prevSpeed; public CeilingFanMediumCommand(CeilingFan ceilingFan) { this.ceilingFan = ceilingFan; } public void execute() { prevSpeed = ceilingFan.getSpeed(); ceilingFan.medium();//将行为的真正执行委托给接收者,此处即ceilingFan风扇对象 } 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(); } } }
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(); } } }
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(); } } }
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; } undoCommand = noCommand; } public void setCommand(int slot, Command onCommand, Command offCommand) { onCommands[slot] = onCommand; offCommands[slot] = offCommand; } //当编号为第slot的开On按钮按下时执行命令 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 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(); } }
public class RemoteLoader { public static void main(String[] args) { RemoteControlWithUndo remoteControl = new RemoteControlWithUndo(); Light livingRoomLight = new Light("Living Room"); LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight); LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight); DimmerLightOnCommand dimmerLightOnCommand=new DimmerLightOnCommand(livingRoomLight); DimmerLightOffCommand dimmerLightOffCommand=new DimmerLightOffCommand(livingRoomLight); CeilingFan ceilingFan = new CeilingFan("Living Room"); CeilingFanHighCommand ceilingFanHigh = new CeilingFanHighCommand(ceilingFan); CeilingFanMediumCommand ceilingFanMedium = new CeilingFanMediumCommand(ceilingFan); CeilingFanLowCommand ceilingFanLow =new CeilingFanLowCommand(ceilingFan); CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan); remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff); remoteControl.setCommand(1, dimmerLightOnCommand, dimmerLightOffCommand); remoteControl.setCommand(2, ceilingFanHigh, ceilingFanOff); remoteControl.setCommand(3, ceilingFanMedium, ceilingFanOff); remoteControl.setCommand(4, ceilingFanLow, ceilingFanOff); remoteControl.onButtonWasPushed(1); remoteControl.onButtonWasPushed(3); remoteControl.onButtonWasPushed(2); remoteControl.offButtonWasPushed(3); remoteControl.undoButtonWasPushed(); } }
Light is dimmed to 75% Living Room ceiling fan is on medium Living Room ceiling fan is on high Living Room ceiling fan is off Living Room ceiling fan is on high
我们可以很轻松地利用组合模式加入宏命令,还有,正如以上代码所示,命令模式的不足之处就是我们需要维护大量的具体命令类。
转载请注明出处:http://blog.csdn.net/jialinqiang/article/details/8943261