定义
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
将请求封装成对象,以便使用不同的请求、队列、或日志将客户端参数化,同时提供可撤销功能。
命令模式可以将“动作的请求者”从“动作的执行者”对象中解耦;被解耦的二者之间通过命令对象进行沟通。
类图
1)Command
public interface Command{ public void execute(); public void undo(); }
2)ConcreteCommand,命令对象将动作和执行者绑定在一起,是请求者和执行者的沟通途径。类比餐厅订单
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动作请求者
请求者不用关心事情是如何完成的。类比餐厅服务员
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动作执行者。
类比餐厅厨师
public class Light{ public void on()... public void off()... }
5)Client,类比顾客
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命令
甲方命令乙方增加页面元素。。顾客在餐厅点餐。。