天天看點

Java設計模式:指令模式(Command Pattern)

指令模式定義

指令模式将“請求”封裝成對象,以便使用不同的請求、隊列或日志來參數化其他對象。指令模式也支援可撤銷的操作。

簡易UML類圖

Java設計模式:指令模式(Command Pattern)

1)Command 為所有指令聲明了一個對象。調用指令對象的excute()方法就可以讓接收者進行相關的動作。它也具備一個undo()方法,支援撤銷。

2)用戶端負責建立某一個具體的指令對象 ConcreteCommand,并設定其接收者Receiver

3)調用者Invoker 持有一個或多個Command指令對象,需設定,并在某個時間點調用  excute()方法

案例

UML類圖

Java設計模式:指令模式(Command Pattern)

說明

1)該例隻使用了兩個裝置 Light 和 CeilingFan 執行個體

2)Nocommand 對象是一個空對象。當你不想傳回一個有意義的對象時,空對象就很有用。用戶端也可以将處理null的責任轉移給空對象。

3)MacroCommand 為 一鍵啟動多功能,一鍵關閉多功能

代碼

Command.java

public interface Command {
	public void execute();
	public void undo();
}
           

NoCommand.java

public class NoCommand implements Command {

	public void execute() {
	}

	public void undo() {
	}
}
           

MacroCommand.java

public class MacroCommand implements Command {

	Command[] commands;
	
	public MacroCommand(Command[] commands){
		this.commands = commands;
	}
	
	public void execute() {
		// TODO Auto-generated method stub
		for (int i = 0; i < commands.length; ++i){
			commands[i].execute();
		}
	}

	public void undo() {
		// TODO Auto-generated method stub
		for (int i = 0; i < commands.length; ++i){
			commands[i].undo();
		}
	}

}
           

Light.java

public class Light {

	String location;
	int level;

	public Light(String location) {
		this.location = location;
	}

	public void on() {
		level = 100;
		System.out.println(location + "Light is on");
	}

	public void off() {
		level = 0;
		System.out.println(location + "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;
	}

}
           

LightOffCommand.java

public class LightOffCommand implements Command {

	Light light;
	
	public LightOffCommand(Light light){
		this.light = light;
	}
	
	public void execute() {
		// TODO Auto-generated method stub
		light.off();
	}

	public void undo() {
		// TODO Auto-generated method stub
		light.on();
	}
}
           

LightOnCommand.java

public class LightOnCommand implements Command {

	Light light;
	
	public LightOnCommand(Light light){
		this.light = light;
	}
	
	public void execute() {
		// TODO Auto-generated method stub
		light.on();
	}

	public void undo() {
		// TODO Auto-generated method stub
		light.off();
	}
}
           

CeilingFan.java

public class CeilingFan {

	String location = "";
	int speed;
	
	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;
		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 + " ceililng 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 on off");
	}
	
	public int getSpeed(){
		return speed;
	}
}
           

CeilingFanHighCommand.java

public class CeilingFanHighCommand implements Command {

	CeilingFan ceilingFan;
	int prevSpeed;
	
	
	public CeilingFanHighCommand(CeilingFan ceilingFan){
		this.ceilingFan = ceilingFan;
	}
	
	public void execute() {
		// TODO Auto-generated method stub
		prevSpeed = ceilingFan.getSpeed();
		ceilingFan.high();
	}

	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();
		}
	}

}
           

CeilingFanMediumCommand.java

public class CeilingFanMediumCommand implements Command {

	CeilingFan ceilingFan;
	int prevSpeed;
	
	
	public CeilingFanMediumCommand(CeilingFan ceilingFan){
		this.ceilingFan = ceilingFan;
	}
	
	public void execute() {
		// TODO Auto-generated method stub
		prevSpeed = ceilingFan.getSpeed();
		ceilingFan.medium();
	}

	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();
		}
	}

}
           

CeilingFanLowCommand.java

public class CeilingFanLowCommand implements Command {

	CeilingFan ceilingFan;
	int prevSpeed;
	
	
	public CeilingFanLowCommand(CeilingFan ceilingFan){
		this.ceilingFan = ceilingFan;
	}
	
	public void execute() {
		// TODO Auto-generated method stub
		prevSpeed = ceilingFan.getSpeed();
		ceilingFan.low();
	}

	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();
		}
	}

}
           

CeilingFanOffCommand.java

public class CeilingFanOffCommand implements Command {

	CeilingFan ceilingFan;
	int prevSpeed;

	public CeilingFanOffCommand(CeilingFan ceilingFan) {
		this.ceilingFan = ceilingFan;
	}

	public void execute() {
		// TODO Auto-generated method stub
		prevSpeed = ceilingFan.getSpeed();
		ceilingFan.off();
	}

	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();
		}
	}
}
           

RemoteControl.java

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) {
		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 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();
	}
}
           

Test.java

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		RemoteControl remoteControl = new RemoteControl();
		
		System.out.println("*************測試燈********************");
		
		Light livingRoomLight = new Light("Living Room");
		LightOnCommand livingroomLightOn = new LightOnCommand(livingRoomLight);
		LightOffCommand livingroomLightOff = new LightOffCommand(livingRoomLight);
		
		remoteControl.setCommand(0, livingroomLightOn, livingroomLightOff);
		
		remoteControl.onButtonWasPushed(0);
		remoteControl.offButtonWasPushed(0);
		System.out.println(remoteControl);
		
		remoteControl.undoButtonWasPushed();
		remoteControl.offButtonWasPushed(0);
		remoteControl.onButtonWasPushed(0);
		System.out.println(remoteControl);
		remoteControl.undoButtonWasPushed();
		
		System.out.println("*************測試吊扇********************");
		
		CeilingFan ceilingFan = new CeilingFan("Living Room");
	
		CeilingFanMediumCommand ceilingFanMedium = new CeilingFanMediumCommand(ceilingFan);
		CeilingFanHighCommand ceilingFanHigh = new CeilingFanHighCommand(ceilingFan);
		CeilingFanOffCommand ceilingFanOff = new CeilingFanOffCommand(ceilingFan);
		
		remoteControl.setCommand(0, ceilingFanMedium, ceilingFanOff);
		remoteControl.setCommand(1, ceilingFanHigh, ceilingFanOff);
		
		remoteControl.onButtonWasPushed(0);
		remoteControl.offButtonWasPushed(0);
		System.out.println(remoteControl);
		remoteControl.undoButtonWasPushed();
		
		remoteControl.onButtonWasPushed(1);
		System.out.println(remoteControl);
		remoteControl.undoButtonWasPushed();
		
		System.out.println("*************測試一鍵啟動多種功能********************");
		Command[] macroOn = {livingroomLightOn, ceilingFanMedium};
		Command[] macroOff = {livingroomLightOff, ceilingFanOff};
		
		MacroCommand onekeyOnMarco = new MacroCommand(macroOn);
		MacroCommand onekeyOffMarco = new MacroCommand(macroOff);
		
		remoteControl.setCommand(2, onekeyOnMarco, onekeyOffMarco);
		
		System.out.println(remoteControl);
		System.out.println("*************一鍵功能啟動********************");
		remoteControl.onButtonWasPushed(2);
		System.out.println("*************一鍵功能關閉********************");
		remoteControl.offButtonWasPushed(2);
	}
}
           

輸出

*************測試燈********************
Living RoomLight is on
Living RoomLight is off

------------- Remote Control ----------
[slot 0] com.jing.command.remote.LightOnCommand	com.jing.command.remote.LightOffCommand
[slot 1] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 2] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 3] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand

Living RoomLight is on
Living RoomLight is off
Living RoomLight is on

------------- Remote Control ----------
[slot 0] com.jing.command.remote.LightOnCommand	com.jing.command.remote.LightOffCommand
[slot 1] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 2] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 3] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand

Living RoomLight is off
*************測試吊扇********************
Living Room ceililng fan is on medium
Living Room ceiling fan is on off

------------- Remote Control ----------
[slot 0] com.jing.command.remote.CeilingFanMediumCommand	com.jing.command.remote.CeilingFanOffCommand
[slot 1] com.jing.command.remote.CeilingFanHighCommand	com.jing.command.remote.CeilingFanOffCommand
[slot 2] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 3] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand

Living Room ceililng fan is on medium
Living Room ceiling fan is on high

------------- Remote Control ----------
[slot 0] com.jing.command.remote.CeilingFanMediumCommand	com.jing.command.remote.CeilingFanOffCommand
[slot 1] com.jing.command.remote.CeilingFanHighCommand	com.jing.command.remote.CeilingFanOffCommand
[slot 2] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 3] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand

Living Room ceililng fan is on medium
*************測試一鍵啟動多種功能********************

------------- Remote Control ----------
[slot 0] com.jing.command.remote.CeilingFanMediumCommand	com.jing.command.remote.CeilingFanOffCommand
[slot 1] com.jing.command.remote.CeilingFanHighCommand	com.jing.command.remote.CeilingFanOffCommand
[slot 2] com.jing.command.remote.MacroCommand	com.jing.command.remote.MacroCommand
[slot 3] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 4] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 5] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand
[slot 6] com.jing.command.remote.NoCommand	com.jing.command.remote.NoCommand

*************一鍵功能啟動********************
Living RoomLight is on
Living Room ceililng fan is on medium
*************一鍵功能關閉********************
Living RoomLight is off
Living Room ceiling fan is on off
           

繼續閱讀