指令模式定義
指令模式将“請求”封裝成對象,以便使用不同的請求、隊列或日志來參數化其他對象。指令模式也支援可撤銷的操作。
簡易UML類圖
1)Command 為所有指令聲明了一個對象。調用指令對象的excute()方法就可以讓接收者進行相關的動作。它也具備一個undo()方法,支援撤銷。
2)用戶端負責建立某一個具體的指令對象 ConcreteCommand,并設定其接收者Receiver
3)調用者Invoker 持有一個或多個Command指令對象,需設定,并在某個時間點調用 excute()方法
案例
UML類圖
說明
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