设计模式第六集——命令模式(Command)
什么时候使用命令模式?当需要将发出请求的对象和执行请求的对象解耦的时候,使用命令模式。
命令模式:将请求封装成对象。
Client创建一个ConcreteCommend,并设置接受者。Command为所有命令生命了一个接口,调用命令对象的execute()方法,可以让接收者进行相关动作。Invoker是命令最终的调用者。
具体例子,现在设计一个遥控器,这个遥控器来控制房间内所有电器的开关。为这个遥控器编程。
以电风扇为例,RemoteLoader创建很多命令对象,然后将他们加载到遥控起的插槽中。每个命令对象都封装了某个家电自动化的一项要求。RemoteControl管理一组命令对象,每个按钮按下的时候就调用相应的onButtonWasPushed()或者offButtonWasPushed(),进而调用execute()方法被调用。
1 package com; 2 3 public interface Command { 4 public void execute(); 5 public void undo(); 6 } 7 8 package com; 9 10 public class FanHighCommand implements Command { 11 Fan fan; 12 int prevSpeed; 13 14 public FanHighCommand(Fan fan) { 15 this.fan = fan; 16 } 17 18 public void execute() { 19 prevSpeed = fan.getSpeed(); 20 21 } 22 23 @Override 24 public void undo() { 25 if (prevSpeed == Fan.High) { 26 fan.high(); 27 } else if (prevSpeed == Fan.Medium) { 28 fan.medium(); 29 } else if (prevSpeed == Fan.Low) { 30 fan.low(); 31 } else if (prevSpeed == Fan.Off) { 32 fan.off(); 33 } 34 } 35 } 36 37 package com; 38 39 public class NoCommand implements Command{ 40 41 @Override 42 public void execute() { 43 // TODO Auto-generated method stub 44 45 } 46 47 @Override 48 public void undo() { 49 // TODO Auto-generated method stub 50 51 } 52 53 } 54 55 package com; 56 57 public class Fan { 58 public static final int High=3; 59 public static final int Medium=2; 60 public static final int Low=1; 61 public static final int Off=0; 62 String location; 63 int speed; 64 65 public Fan(String location) { 66 this.location = location; 67 speed=Off; 68 } 69 //设置吊扇速度 70 public void high(){ 71 speed=High; 72 } 73 public void medium(){ 74 speed=Medium; 75 } 76 public void low(){ 77 speed=Low; 78 } 79 public void off(){ 80 speed=Off; 81 } 82 //返回当前吊扇速度,为undo使用 83 public int getSpeed(){ 84 return speed; 85 } 86 } 87 88 89 package com; 90 91 public class RemoteControl { 92 Command[] onCommands; 93 Command[] offCommands; 94 Command undoCommand; 95 96 public RemoteControl(){ 97 onCommands=new Command[3];//假设共控制三种电器 98 offCommands=new Command[3]; 99 100 Command noCommand=new NoCommand(); 101 for(int i=0;i<3;i++){ 102 onCommands[i]=noCommand; 103 offCommands[i]=noCommand; 104 } 105 undoCommand=noCommand; 106 } 107 public void setCommand(int slot,Command onCommand,Command offCommand){ 108 onCommands[slot]=onCommand; 109 offCommands[slot]=offCommand; 110 } 111 public void onButtonWasPushed(int slot){ 112 onCommands[slot].execute(); 113 undoCommand=onCommands[slot]; 114 } 115 public void offButtonWasPushed(int slot){ 116 offCommands[slot].execute(); 117 undoCommand=offCommands[slot]; 118 } 119 public void undoButtonWashPushed(){ 120 undoCommand.undo(); 121 } 122 }