命令(模式)的结构很简单,但对于消除代码间的耦合却有着重要的影响。
在 C 语言中我们经常使用回调函数,而命令模式是回调( callback )的面向对象的替代物。从最直观的角度来看,命令模式就是一个函数对象:一个作为对象的函数。通过将函数封装为对象,就能够以参数的形式将其传递给其他函数或者对象,告诉他们在履行请求的过程中执行特定的操作。可以说,命令模式是携带行为信息的信使。
命令模式对于构建 GUI 应用有特别重要的意义,比如菜单的响应,使用 MFC 时我们通过一系列的 on_command 宏来关联菜单操作,而如果采用命令模式和工厂模式,将可以得到更精巧的实现。
意图
- 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
- Qt , QAction
- Command 对象生命周期维护
- 抽象出待执行的动作以参数化某对象。
- 在不确定的时刻指定、排列和执行请求
- 支持取消操作
- 支持修改日志
- 用构建在原语操作上的高层操作构造一个系统
- 不关注怎样执行,只关注有对象可以接受执行请求
- class CommandObject
- {
- public:
- CommandObject(){}
- virtual ~CommandObject(){}
- virtual void execute() = 0;
- };
- class EchoCommand: public CommandObject
- {
- public:
- void execute()
- {
- cout << "I\'m echo command";
- }
- };
- class HelloCommand: public CommandObject
- {
- public:
- void execute()
- {
- cout << "Hello hello, how are you";
- }
- };
接下来看另外一个有点实际意义的例子。假如我们实现一个 GUI 程序,主页面上有多个按钮,点击按钮后会执行一个命令,如打开新窗口、打开浏览器、打开文件夹、退出程序之类的。
命令模式实例2
- class CPushButton : public IButton {
- public:
- void setCommandObject(CommandObject * commandObject){
- if(m_pCommand)
- {
- delete m_pCommand;
- }
- m_pCommand = commandObject;
- }
- void onClicked()
- {
- m_pCommand->execute();
- }
- private:
- CommandObject * m_pCommand;
- };