command(命令模式)——对象行为型模式
1.意图
将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,请求配对或者记录请求日志,以及支持可撤销的操作。
2.动机
有时必须向某对象递交请求,但是并不知道关于被请求的操作或者请求的接受者的任何信息。
命令模式通过将请求本身变成一个对象可向未指定的应用对象提出请求。这个对象可被储存并且可以像其他对象一样传递。
关键是一个抽象的command类,定义了一个执行操作的接口,其最简单的形式是一个抽象的execute操作。具体的command子类将接受者作为其一个实例变量,并实现execute操作,指定接受者采取的动作。而接受者有执行该请求所需的具体信息。
3.适用性
1)抽象出待执行的动作以参数化某对象。可以用回调函数来表达这种参数化机制。command模式是回调机制的一个面向对象的替代品。
2)在不同的时刻指定、排列和执行请求。
3)支持取消操作
4)支持修改日志
5)用构建在原语上的高层操作构造一个系统。
4.结构
参考:http://www.cnblogs.com/rosesmall/archive/2012/03/26/2418319.html
5.参与者
command
声明执行操作的接口
concreteCommand
将一个接受者对象绑定于一个动作
调用接收者相应的操作,以实现execute
client
创建一个具体命令对象并设定他是接收者
invoker
要求该命令执行这个请求
receiver
知道如何实施与执行一个请求相关的操作。任何类都可以成为一个接收者。
6.协作
client创建一个concreteCommand对象并制定它的receiver对象
某invoker对象存储该concreteCommand对象
该invoker通过调用command对象的excute操作来递交一个请求。
concreteCommand对象调用它的receiver的一些操作以执行该请求。
7.效果
1)command模式将调用操作的对象和知道如何实现该操作的对象解耦
2)command是头等对象。他们可以像其他的对象一样被操纵和扩展
3)你可以多个命令合成一个命令
4)增加新的command很容易,无需改变已有的类
8.实现
1)一个命令对象该智能到何种程度
2)支持取消和重做操作
concretecommand需要存储额外的状态
3)避免取消操作过程中的错误积累
4)使用c++中的模板
9.代码示例
#include<iostream> using namespace std; class TV { public: TV(string str) { cout<<"here is a TV"<<endl; name = str; } void turnOn() { cout<<"The TV is on"<<endl; } void turnOff() { cout<<"The TV is off"<<endl; } string name; }; class command { public: virtual void on(){}; virtual void off(){}; }; class TVcommand:public command { public: TVcommand(TV *t) { tv = t; cout<<"TV command get a object called "<<t->name<<endl; } void on() { tv->turnOn(); } void off() { tv->turnOff(); } private: TV *tv; }; class remoteController:public command { public: remoteController(command *c) { cout<<"the remote controller get a command"<<endl; com = c; } void turnOn() { com->on(); } void turnOff() { com->off(); } private: command *com; }; int main() { TV *t = new TV("myTV"); command *c = new TVcommand(t); remoteController *controller = new remoteController(c); controller->turnOn(); controller->turnOff(); }
10.相关模式
composite可以用来实现宏命令
memento可以用来保持某个状态