继续上部分的说
在之前的文章最后写了一个带有撤销电灯功能的遥控器功能,通常,想要实现撤销的功能,需要记录撤销之前的状态是什么,就比方说电扇,允许有多个风速状态,也允许被关闭。
直接上代码。
1、风扇类
package CeilingFan;
/**
* 使用状态实现撤销
* 风扇类
* @author Joy
*
*/
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;
}
// 高转速
public void high() {
speed = HIGH;
System.out.println(location+"风扇正在高转速运行");
}
// 中转速
public void medium() {
speed = MEDIUM;
System.out.println(location+"风扇正在中转速运行");
}
// 低转速
public void low() {
speed = LOW;
System.out.println(location+"风扇正在低转速运行");
}
// 关闭吊扇
public void off() {
speed = OFF;
System.out.println(location+"风扇关闭");
}
//获取当前吊扇速度
public int getSpeed(){
return speed;
}
}
2、命令类
package CeilingFan;
public interface Command {
public void execute();
public void undo();
}
3、下面是风扇高、中、低关闭的具体实现类
package CeilingFan;
/**
* 风扇高速操作
*
* @author Joy
*
*/
public class CeilingFanHighCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed;
public CeilingFanHighCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}
// 执行
@Override
public void execute() {
// 执行方法前,先获取之前的状态并记录下来
prevSpeed = ceilingFan.getSpeed();
ceilingFan.high();
}
// 撤销
@Override
public void undo() {
// 将风扇的速度设置为之前的状态,达到撤销目的
switch (prevSpeed) {
case CeilingFan.HIGH:
ceilingFan.high();
break;
case CeilingFan.MEDIUM:
ceilingFan.medium();
break;
case CeilingFan.LOW:
ceilingFan.low();
break;
case CeilingFan.OFF:
ceilingFan.off();
break;
}
}
}
package CeilingFan;
/**
* 风扇中速操作
* @author Joy
*
*/
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() {
switch (prevSpeed) {
case CeilingFan.HIGH:
ceilingFan.high();
break;
case CeilingFan.MEDIUM:
ceilingFan.medium();
break;
case CeilingFan.LOW:
ceilingFan.low();
break;
default:
ceilingFan.off();
break;
}
}
}
package CeilingFan;
/**
* 风扇低速操作
* @author Joy
*
*/
public class CeilingFanLowCommand implements Command {
CeilingFan ceilingFan;
int prevSpeed;
public CeilingFanLowCommand(CeilingFan ceilingFan) {
this.ceilingFan = ceilingFan;
}
@Override
public void execute() {
prevSpeed = ceilingFan.getSpeed();
ceilingFan.low();
}
@Override
public void undo() {
switch (prevSpeed) {
case CeilingFan.HIGH:
ceilingFan.high();
break;
case CeilingFan.MEDIUM:
ceilingFan.medium();
break;
case CeilingFan.LOW:
ceilingFan.low();
break;
default:
ceilingFan.off();
break;
}
}
}
package CeilingFan;
/**
* 风扇关闭
* @author Joy
*
*/
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() {
switch (prevSpeed) {
case CeilingFan.HIGH:
ceilingFan.high();
break;
case CeilingFan.MEDIUM:
ceilingFan.medium();
break;
case CeilingFan.LOW:
ceilingFan.low();
break;
default:
ceilingFan.off();
break;
}
}
}
4、无操作类接口
package CeilingFan;
public class NoCommand implements Command {
public void execute() { }
public void undo() { }
}
5、调用者
package CeilingFan;
/**
* 调用者
* @author Joy
*
*/
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;
}
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------ 遥控器 -------\n");
for (int i = 0; i < onCommands.length; i++) {
stringBuff.append("[插槽 " + i + "] " + onCommands[i].getClass().getName()
+ " " + offCommands[i].getClass().getName() + "\n");
}
stringBuff.append("[撤销] " + undoCommand.getClass().getName() + "\n");
return stringBuff.toString();
}
}
6、测试类
package CeilingFan;
public class TestMain {
public static void main(String[] args) {
//实例化遥控器
RemoteControlWithUndo remoteControl=new RemoteControlWithUndo();
CeilingFan ceilingFan=new CeilingFan("卧室");
//这里高中低速 关闭分别实例化
CeilingFanHighCommand highCommand=new CeilingFanHighCommand(ceilingFan);
CeilingFanMediumCommand mediumCommand=new CeilingFanMediumCommand(ceilingFan);
CeilingFanLowCommand lowCommand=new CeilingFanLowCommand(ceilingFan);
CeilingFanOffCommand offCommand=new CeilingFanOffCommand(ceilingFan);
//遥控器加载中速和高速的开启和关闭方法
remoteControl.setCommand(0, mediumCommand, offCommand);
remoteControl.setCommand(1, highCommand, offCommand);
//先以中速开启吊扇
remoteControl.onButtonWasPushed(0);
//关闭吊扇
remoteControl.offButtonWasPushed(0);
//显示插槽调用信息
System.out.println(remoteControl.toString());
//撤销,会变为中速
remoteControl.undoButtonWasPushed();
remoteControl.onButtonWasPushed(1);
System.out.println(remoteControl.toString());
remoteControl.undoButtonWasPushed();
}
}
7、效果图
其实命令模式还能用于宏命令,队列请求,日志请求,命令模式我理解的很一般,往后我还会补充修改此篇内容。
要点:
1:命令模式将发出请求的对象和执行请求的对象解耦。
2:被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接收者和一个或一组对象
3:调用者通过调用命令对象的execute方法发出请求,这会使得的接收者的动作被调用。
4:命令可以支持撤销动作,实现一个undo方法来回到execute被执行前的状态。
感谢你看到这里,命令模式到这里就结束了,本人文笔随便,若有不足或错误之处望给予指点,90度弯腰~~~很快我会发布下一个设计模式的内容,生命不息,编程不止!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。