宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取

定义

将一个请求封装为一个对象,实现请求者与实施者的低耦合。

案例

大部分应用都存在非常多的菜单和一些操作button,但在设计这些菜单和button的时候,并不知道它要运行什么样的操作。在设计删除、复制和撤销这些详细实现的时候,也不知道在要什么地方用到,可能是代码里面直接调用,也可能是界面上点击了某个button后发生的操作。为了解决菜单和详细操作的这样的耦合度,就须要使用Command-命令模式:

菜单类的每个Item都保存一个Command子类的对象实例,当界面点击的时候,就调用Command的execute()方法,在Command子类的execute()方法里面会直接调用Receiver的action()方法,就运行详细的操作。

class MenuItem {public:    void setCommand(Command* comand) { m_command = command; }    void onClicked() {        m_command->execute();    }private:    Command* command;}class Command {public:    virtual void execute();    virtual bool isEnable();};class CopyCommand {public:    virtual void execute() {        m_receiver->action();    }private:    CopyReceiver* m_receiver;};class DeleteCommand {public:    virtual void execute() {        m_enable = m_receiver->action();    }    bool isEnable() {        return m_enable;    }private:    DeleteReceiver* m_receiver;    bool m_enable;};

一个Command对象还能够被不同的Invoker对象保存,用以实现相同的操作:

MenuItem* copyItem = new MenuItem("Copy");MenuItem* deleteItem = new MenuItem("Delete");MenuItem* undoItem = new MenuItem("Undo");Button* copyButton = new Button("Copy");Button* deleteButton = new Button("Delete");Button* undoButton = new Button("Undo");Command* copyCommand = new CopyCommand();Command* deleteCommand = new DeleteCommand();Command* undoCommand = new UndoCommand();copyItem->setCommand(copyCommand);deleteItem->setCommand(deleteCommand);undoItem->setCommand(undoCommand);copyButton->setCommand(copyCommand);deleteButton->setCommand(deleteCommand);undoButton->setCommand(undoCommand);

同样的操作都使用同一个对象,当undoCommond的enable()返回false的时候,菜单和button都不能使用了。

适用性

抽象出待运行的操作以參数化某对象,Command模式就像一个回调函数的对象实现。在不同的时刻指定、排列和运行请求,Commad有一个与初始请求无关的生存期。能够支持取消操作,在Command对象运行execute方法的之前把信息保存,提供一个unExecute方法恢复在运行前。也能够使用一个专门的Command来保存全部运行了的Commond对象比方UndoCommand来达到回滚操作。支持事物(Transaction),对一系列数据进行提交操作。