命令模式就是通过封装方法调用,把运算块包装成形。调用此运算的对象不需要关心事情是如何进行的,只要知道如何使用包装成型的方法就可以了;
定义:将“请求”封装成对象,以为使用不同的额请求、队列或者日志来参数化其他对象。
下面讲解下遥控器的设计,以下是遥控器的基本模型:
左边是插槽,每个插槽都有对应的执行对象,右边是on和off开关,同时还有undo开关;
命令模式就是:客户端想要发出命令或者请求,不关心请求的真正接收者是谁,比如客户按下第一行的on,想要起居室的灯亮起来,而不关心是具体哪个light的来实现;
分析:
1,命令模式中,会定义一个命令接口(Command接口),用来约束所有的命令对象(ConcreteCommand类),然后提供具体的命令实现形式,每个命令实现对象是对客户端某个请求的封装(每个ConcreteCommand对象对应某种具体的行为);
2,在命令模式中,命令对象并不知道如何处理命令,而是由相应的接收者对象来真正的执行命令;(也就是说ConcreteCommand的执行时有Receiver来执行的)
3,命令模式中,命令对象和接收者对象的关系,并不是余生具有的,需要一个装配的过程,(也就是说将具体的命令存放在Invoker中);
类图如下所示:
针对遥控器的分析:(1,2,3与上边的分析对应)
-
定义命令的同一接口command,然后所有的命令对象lightOnCommand,lightOffCommand,garageDoorUpCommand,garageDoorDownCommand,allLightOnCommand,allLightOffCommand等每一个对象对应一个按钮;
-
lightOnCommand就是接收者是light,garageDoorUpCommand的接收者garageDoor,allLightOffCommand的接收者是一些必要的对象等。。。
-
remoteControl遥控器装配这些对象。。
对于遥控器的设计类如下所示:(省略掉部分:)
Command接口:
interface Command{
public void execute();
public void undo();
}
Receive类:
class Light{
String str;
public Light(String str){
this.str = str;
}
public void on(){
System.out.println("light on!!!");
}
public void off(){
System.out.println("light off!!!");
}
}
class GarageDoor{
public void open(){
System.out.println("GarageDoor open!!!");
}
public void close(){
System.out.println("GarageDoor close!!!");
}
}
ConcreteCommand类:
class LightOnCommand implements Command{
Light light;
public LightOnCommand(Light light){
this.light = light;
}
@Override
public void execute() {
// TODO Auto-generated method stub
light.on();
}
@Override
public void undo() {
// TODO Auto-generated method stub
light.off();
}
}
class LightOffCommand implements Command{
Light light;
public LightOffCommand(Light light){
this.light = light;
}
@Override
public void execute() {
// TODO Auto-generated method stub
light.off();
}
@Override
public void undo() {
// TODO Auto-generated method stub
light.on();
}
}
class GarageDoorOpenCommand implements Command{
GarageDoor gd;
public GarageDoorOpenCommand(GarageDoor gd){
this.gd = gd;
}
@Override
public void execute() {
// TODO Auto-generated method stub
gd.open();
}
@Override
public void undo() {
// TODO Auto-generated method stub
gd.close();
}
}
class GarageDoorCloseCommand implements Command{
GarageDoor gd;
public GarageDoorCloseCommand(GarageDoor gd){
this.gd = gd;
}
@Override
public void execute() {
// TODO Auto-generated method stub
gd.close();
}
@Override
public void undo() {
// TODO Auto-generated method stub
gd.open();
}
}
class NoCommand implements Command{
@Override
public void execute() {
// TODO Auto-generated method stub
}
@Override
public void undo() {
// TODO Auto-generated method stub
}
}
Invoker类:
class RemoteControl{
Command[] onCommands;
Command[] offCommands;
public RemoteControl(){
onCommands = new Command[5];
offCommands = new Command[5];
Command noCommand = new NoCommand();
for(int i=0;i<5;i++){
onCommands[i] = noCommand;
offCommands[i] = noCommand;
}
}
public void setCommand(int slot,Command onc,Command offc){
onCommands[slot] = onc;
offCommands[slot] = offc;
}
public void onButtonWasPushed(int slot){
onCommands[slot].execute();
}
public void offButtonWasPushed(int slot){
offCommands[slot].execute();
}
public String toString(){
StringBuffer sb = new StringBuffer();
sb.append("\n---------Remote Control----------\n");
for(int i=0;i<onCommands.length;i++){
sb.append("[slot"+i+"]"+onCommands[i].getClass().getName()+" "+offCommands[i].getClass().getName()+"\n");
}
return sb.toString();
}
}
Client类:
class RemoteLoader{
public static void Load(RemoteControl rc){
Light LightLR = new Light("Living Room");
Light LightKR = new Light("Kirchen Room");
GarageDoor gd = new GarageDoor();
LightOnCommand LRLighton = new LightOnCommand(LightLR);
LightOnCommand KRLighton = new LightOnCommand(LightKR);
LightOffCommand LRLightoff = new LightOffCommand(LightLR);
LightOffCommand KRLightoff = new LightOffCommand(LightKR);
GarageDoorOpenCommand gdoc = new GarageDoorOpenCommand(gd);
GarageDoorCloseCommand gdcc = new GarageDoorCloseCommand(gd);
rc.setCommand(0, LRLighton, LRLightoff);
rc.setCommand(1, KRLighton, KRLightoff);
rc.setCommand(2, gdoc, gdcc);
}
}
测试代码:
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
RemoteControl rc = new RemoteControl();
RemoteLoader.Load(rc);
rc.onButtonWasPushed(0);
rc.offButtonWasPushed(0);
rc.onButtonWasPushed(1);
rc.offButtonWasPushed(1);
rc.onButtonWasPushed(2);
rc.offButtonWasPushed(2);
rc.onButtonWasPushed(3);
rc.offButtonWasPushed(3);
}
}