命令模式
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;
}