首页 > 代码库 > 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释

设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释

命令模式(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) { //开启button
		onCommands[slot].execute();
		undoCommand = onCommands[slot];
	}
	
	public void offButtonWasPushed(int slot) { //关闭button
		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








设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释