1、定义:
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,命令模式也支持可撤销的操作。
命令可以用来实现日志和事务系统。
2、实例:
1)需求:设计一个家电遥控器的API,遥控器具有7个可编程的插槽,每个插槽都具有对应的开关按钮,另外还具备撤销按钮,用来撤销上一步的操作。
2)代码实现:
a)命令实现
/* 遥控器命令接口,实现遥控器的动作 */ public interface Command { public void execute(); public void undo(); } /* 空对象,用于返回一个没有意义的对象*/ public class NoCommand implements Command{ @Override public void execute() { } @Override public void undo() { } }
b) 命令对象
public class Light { private String name; public Light(String name) { this.name = name; } public Light() { } public void lightOn(){ System.out.println(name + " light is on!"); } public void lightOff(){ System.out.println(name + " light is off!"); } } public class LightOnCommand implements Command { Light light = new Light(); public LightOnCommand(Light light) { this.light = light; } @Override public void execute() { light.lightOn(); } @Override public void undo() { light.lightOff(); } } public class LightOffCommand implements Command { Light light = new Light(); public LightOffCommand(Light light) { this.light = light; } @Override public void execute() { light.lightOff(); } @Override public void undo() { light.lightOn(); } }
c) 命令对象管理
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(); } @Override public String toString() { StringBuffer strBuff = new StringBuffer(); strBuff.append(" ===========Remote Control============= "); for(int i=0;i<onCommands.length;i++){ strBuff.append("[slot "+i+"]"+onCommands[i].getClass().getName()+" " +offCommands[i].getClass().getName()+" "); } return strBuff.toString(); } }
d) 测试代码:
public class RemoteLoader { public static void main(String[] args) { RemoteControl remoteControl = new RemoteControl(); Light livingRoomLight = new Light("living Room"); Light kitchenLight = new Light("kitchen"); Light washingRoomLight = new Light("washing Room"); LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight); LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight); LightOnCommand kitchenLightOn = new LightOnCommand(kitchenLight); LightOffCommand kitchenLightOff = new LightOffCommand(kitchenLight); LightOnCommand washingRoomLightOn = new LightOnCommand(washingRoomLight); LightOffCommand washingRoomLightOff = new LightOffCommand(washingRoomLight); remoteControl.setCommand(0,livingRoomLightOn,livingRoomLightOff); remoteControl.setCommand(1,kitchenLightOn,kitchenLightOff); remoteControl.setCommand(2,washingRoomLightOn,washingRoomLightOff); System.out.println(remoteControl); remoteControl.onButtonWasPushed(0); remoteControl.onButtonWasPushed(1); remoteControl.onButtonWasPushed(2); remoteControl.offButtonWasPushed(0); remoteControl.offButtonWasPushed(1); remoteControl.offButtonWasPushed(2); remoteControl.undoButtonWasPushed(); } }
测试结果:
===========Remote Control=============
[slot 0]com.zte.common.utils.DesignPattern.CommandPattern.LightOnCommand com.zte.common.utils.DesignPattern.CommandPattern.LightOffCommand
[slot 1]com.zte.common.utils.DesignPattern.CommandPattern.LightOnCommand com.zte.common.utils.DesignPattern.CommandPattern.LightOffCommand
[slot 2]com.zte.common.utils.DesignPattern.CommandPattern.LightOnCommand com.zte.common.utils.DesignPattern.CommandPattern.LightOffCommand
[slot 3]com.zte.common.utils.DesignPattern.CommandPattern.NoCommand com.zte.common.utils.DesignPattern.CommandPattern.NoCommand
[slot 4]com.zte.common.utils.DesignPattern.CommandPattern.NoCommand com.zte.common.utils.DesignPattern.CommandPattern.NoCommand
[slot 5]com.zte.common.utils.DesignPattern.CommandPattern.NoCommand com.zte.common.utils.DesignPattern.CommandPattern.NoCommand
[slot 6]com.zte.common.utils.DesignPattern.CommandPattern.NoCommand com.zte.common.utils.DesignPattern.CommandPattern.NoCommand
living Room light is on!
kitchen light is on!
washing Room light is on!
living Room light is off!
kitchen light is off!
washing Room light is off!
washing Room light is on!