[设计模式总结] . 命令模式

2014-11-24 11:52:33 · 作者: · 浏览: 17

定义
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

将请求封装成对象,以便使用不同的请求、队列、或日志将客户端参数化,同时提供可撤销功能。

命令模式可以将“动作的请求者”从“动作的执行者”对象中解耦;被解耦的二者之间通过命令对象进行沟通。

类图

\

1)Command


[java]
public interface Command{
public void execute();
public void undo();
}

public interface Command{
public void execute();
public void undo();
}
2)ConcreteCommand,命令对象将动作和执行者绑定在一起,是请求者和执行者的沟通途径。类比餐厅订单


[java]
public class LightOnCommand implements Command{
//Reciever
Light light;
public LightOnCommand(Light light){
this.light = light
}

public void execute(){
light.on();
}
public void undo(){
light.off();
}
}

public class LightOnCommand implements Command{
//Reciever
Light light;
public LightOnCommand(Light light){
this.light = light
}

public void execute(){
light.on();
}
public void undo(){
light.off();
}
}


3)Invoker动作请求者

请求者不用关心事情是如何完成的。类比餐厅服务员

[java]
public class Invoker{
//Command
Command cmd;
public voic setCommand(Command cmd){
this.cmd = cmd;
}

public void buttonAction(){
cmd.execute();
}
public void undoBtnAction(){
cmd.undo();
}
}

public class Invoker{
//Command
Command cmd;
public voic setCommand(Command cmd){
this.cmd = cmd;
}

public void buttonAction(){
cmd.execute();
}
public void undoBtnAction(){
cmd.undo();
}
}
4)Receiver动作执行者。类比餐厅厨师

[java]
public class Light{
public void on()...
public void off()...
}

public class Light{
public void on()...
public void off()...
}
5)Client,类比顾客


[java]
public class Client{
public static void main(String[] args){

//Receiver
Light light = new Light("room light");
//Concrete Command
LightOnCommand cmd = new LightOnCommand(light);

//Invoker
Invoker invoker = new Invoker();
invoker.setCommand(cmd);
invoker.buttonAction();

}
}

public class Client{
public static void main(String[] args){

//Receiver
Light light = new Light("room light");
//Concrete Command
LightOnCommand cmd = new LightOnCommand(light);

//Invoker
Invoker invoker = new Invoker();
invoker.setCommand(cmd);
invoker.buttonAction();

}
}


优点
1)解耦:

Invoker和Receiver完全解耦,不需要直接沟通。

Command对象中封装了Receiver,及其要做的事情。


2)可扩展

日后增加Command的子类,即可增加功能。


3)可结构其他模式,例如责任链模式、模板方法模式

缺点
Command子类可能会非常多。(可结合模板方法模式解决)


使用场景
任何涉及“命令”的地方都可使用;例如GUI按钮点击、DOS命令

甲方命令乙方增加页面元素。。顾客在餐厅点餐。。