您的位置:首页 > 其它

设计模式介绍之三:命令模式(command)

2014-01-09 23:03 531 查看
命令(模式)的结构很简单,但对于消除代码间的耦合却有着重要的影响。

在 C 语言中我们经常使用回调函数,而命令模式是回调( callback )的面向对象的替代物。从最直观的角度来看,命令模式就是一个函数对象:一个作为对象的函数。通过将函数封装为对象,就能够以参数的形式将其传递给其他函数或者对象,告诉他们在履行请求的过程中执行特定的操作。可以说,命令模式是携带行为信息的信使。

命令模式对于构建 GUI 应用有特别重要的意义,比如菜单的响应,使用 MFC 时我们通过一系列的 on_command 宏来关联菜单操作,而如果采用命令模式和工厂模式,将可以得到更精巧的实现。

意图

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

已知应用举例

Qt , QAction

常见问题

Command 对象生命周期维护

适用环境

抽象出待执行的动作以参数化某对象。
在不确定的时刻指定、排列和执行请求
支持取消操作
支持修改日志
用构建在原语操作上的高层操作构造一个系统
不关注怎样执行,只关注有对象可以接受执行请求

命令模式实例1

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";
    }
};
我们可以把 EchoCommand 和 HelloCommand 两个命令对象传递出去,其他部分的代码只需要知道在特定条件发生时有对象执行命令,而无需知道是谁、在执行什么命令。

接下来看另外一个有点实际意义的例子。假如我们实现一个 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;
};
我们可以把按钮的信息写在配置文件中,如名字、图标、位置等,而每个按钮要执行的命令通过一个字符串表示,也写在配置文件中。程序启动时解析配置文件,生成界面,根据配置文件中的命令字符串通过工厂模式创建一个命令对象并与按钮关联(如上面的代码所示,通过 setCommandObject 方法给按钮设置命令对象),这样一个极具扩展性的程序就完成了。

接下来会介绍工厂模式,结合单例模式、命令模式,实现一个有意义的例子。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: