【设计模式】之二十三种设计模式--命令模式

命令模式

Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.

(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)

通用类图

接受者角色,实现具体的命令(程序员,美工等角色)

命令角色,声明需要执行的命令(甲方)

调用者角色,接受命令,并执行命令(项目经理)

通用源码

//接受者类
class Receiver {
public:
    virtual void doSomething() = 0;
};
class ConcreteReceiver1 : public Receiver {
public:
    virtual void doSomething() {
        //业务逻辑
    }
}
class ConcreteReceiver2 : public Receiver {
public:
    virtual void doSomething() {
        //业务逻辑
    }
}
//命令者类
class Command {
public:
    virtual void execute() = 0;
};
class ConcreteCommand1 : public Command {
private:
    Receiver receiver;
public:
    ConcreteCommand1(Receiver r) {
        receiver = r;
    }
    virtual void execute() {
        receiver.doSomething();
    }
};
class ConcreteCommand2 : public Command {
private:
    Receiver receiver;
public:
    ConcreteCommand2(Receiver r) {
        receiver = r;
    }
    virtual void execute() {
        receiver.doSomething();
    }
};
//调用者类
class Invoker {
private:
    Command command;
    void setCommand(Command c) { command = c;}
    void action() {command.execute(); }
}

优点

类间解耦,调用者角色和接受者角色之间没有依赖。通过Command抽象类的execute方法就行

可扩展性,需要新加什么命令只需要继承Command即可

命令模式结合其他模式会更优秀,结合模板方法模式,减少Command子类的膨胀问题。

缺点

Command的子类可能会膨胀得非常大

扩展

客户端只需要发布命令,至于实现,可以内部自行处理。

撤回命令,根据事物日志回滚,或者缓存状态。

示例代码

#include <iostream>
#include <string>

using namespace std;

void input(string s) {
    cout << s << endl;
}

class Group {
public:
    virtual void find() = 0;
    virtual void add() = 0;
    virtual void deleted() = 0;
    virtual void change() = 0;
    virtual void plan() = 0;
};

class RequirementGroup : public Group {
public:
    virtual void find() {
        input("find RequirementGroup");
    }
    virtual void add() {
        input("add a Requirement");
    }
    virtual void change() {
        input("change a Requirement");
    }
    virtual void deleted() {
        input("delete a Requirement");
    }
    virtual void plan() {
        input("plan a Requirement");
    }
};
class PageGroup : public Group {
public:
    virtual void find() {
        input("find PageGroup");
    }
    virtual void add() {
        input("add a Page");
    }
    virtual void change() {
        input("change a Page");
    }
    virtual void deleted() {
        input("delete a Page");
    }
    virtual void plan() {
        input("plan a Page");
    }
};
class CodeGroup : public Group {
public:
    virtual void find() {
        input("find CodeGroup");
    }
    virtual void add() {
        input("add a Function");
    }
    virtual void change() {
        input("change a Function");
    }
    virtual void deleted() {
        input("delete a Function");
    }
    virtual void plan() {
        input("plan a Function");
    }
};

class Command {
protected:
    RequirementGroup *rg = new RequirementGroup();
    PageGroup *pg = new PageGroup();
    CodeGroup *cg = new CodeGroup();
public:
    virtual void execute() = 0;
    ~Command() {
        delete rg;
        delete pg;
        delete cg;
    }
};

class AddRequirementCommand : public Command {
public:
    virtual void execute() {
        rg->find();
        rg->add();
        rg->plan();
    }
};

class DeletePageCommand : public Command {
public:
    virtual void execute() {
        pg->find();
        pg->deleted();
        pg->plan();
    }
};

class Invoker {
private:
    Command* mcommand;
public:
    void setCommand(Command *command) {
        mcommand = command;
    }
    void action() {
        mcommand->execute();
    }
};

int main() {
    Invoker pm;
    Command *command = new AddRequirementCommand();
    pm.setCommand(command);
    pm.action();
    delete command;
    return 0;
}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦