行为型模式 ######################################## 行为型模式关注于对象之间的通信。 责任链模式 **************************************** 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链路,并沿着这条链传递该请求,直到有一个对象处理它为止。 .. code-block:: cpp class Handler { protected: Handler* successor; public: void setSuccessor(Handler* successor) { this->successor = successor; } virtual void HandleRequest(int request) = 0; }; class ConcreteHandler1 : public Handler { public: void HandleRequest(int request) override { if (request <= 10) { for (int i = 0; i <= 10; ++i) { cout << "HandleRequest1 handle " << i << endl; } } else if (this->successor) { this->successor->HandleRequest(request); } } }; class ConcreteHandler2 : public Handler { public: void HandleRequest(int request) override { if (request > 10 && request <= 20) { for (int i = 10; i <= 20; ++i) { cout << "HandleRequest2 handle " << i << endl; } } else if (this->successor) { this->successor->HandleRequest(request); } } }; class ConcreteHandler3 : public Handler { public: void HandleRequest(int request) override { if (request > 20 && request <= 30) { for (int i = 20; i <= 30; ++i) { cout << "HandleRequest3 handle " << i << endl; } } else if (this->successor) { this->successor->HandleRequest(request); } } }; // 使用 ConcreteHandler1 handle1; ConcreteHandler2 handle2; ConcreteHandler3 handle3; handle1.setSuccessor(&handle2); handle2.setSuccessor(&handle3); handle1.HandleRequest(30); 命令模式 **************************************** 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或者记录记录日志,以及支持可撤销的操作。 .. code-block:: cpp class Allocator { public: template void Execute(T t) { // t 是一个返回类型为 可打印类型的可调用对象 cout << "Allocator 执行:" << t() << endl; } }; class Command { protected: Allocator alloc; public: void bind(Allocator& alloc) { this->alloc = alloc; } virtual void Execute() = 0; }; class MemeryCommand : public Command { public: void Execute() override { this->alloc.Execute([]() { return "获取内存资源"; }); } }; class PortCommand : public Command { public: void Execute() override { this->alloc.Execute([]() { return "获取端口资源"; }); } }; class Invoke { Allocator alloc; list commandList; size_t memery = 500; // 内存资源一共 500 MB size_t port = 3; // 端口资源一共3个 public: Invoke(Allocator& alloc) : alloc(alloc) { } void addCommand(Command* cmd) { if (dynamic_cast(cmd)) { // 若请求的是内存资源 if (memery > 0) { // 若内存资源充足 commandList.push_back(cmd); memery -= 200; } else { cout << "内存资源不足" << endl; } } else { // 否则请求的为端口资源 if (port > 0) { commandList.push_back(cmd); port -= 1; } else { cout << "端口资源不足" << endl; } } } void rollback(Command* cmd) { commandList.remove(cmd); } void commit() { for (auto cmd : commandList) { cmd->bind(alloc); cmd->Execute(); } } }; // 使用 Allocator alloc; Invoke in(alloc); MemeryCommand mcmd1; MemeryCommand mcmd2; PortCommand pcmd1; PortCommand pcmd2; PortCommand pcmd3; PortCommand pcmd4; in.addCommand(&mcmd1); in.addCommand(&mcmd2); in.addCommand(&pcmd1); in.addCommand(&pcmd2); in.addCommand(&pcmd3); in.addCommand(&pcmd4); in.rollback(&pcmd3); in.commit(); 解释器模式 **************************************** 解释器模式:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。 如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题 迭代器模式 **************************************** 迭代器模式提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。 中介者模式 **************************************** 中介者模式是迪米特法则的践行者,通过在复杂系统中引入中介者来简化系统结构。通过引入中介者,将复杂的网状交互转变为更加简单的星状交互。 备忘录模式 **************************************** 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 .. code-block:: cpp struct State { int hp; int mp; }; class Memento { State state; public: void setMemento(const State& state) { this->state = state; } const State getState() { return state; } }; class Player { State state; int id; public: Memento* createMemento() { return new Memento; } void setMemento(Memento* mem) { mem->setMemento(state); } }; class CareTaker { Memento* mem = nullptr; public: void setMemento(Memento* mem) { this->mem = mem; } Memento* getMemento() { return this->mem; } }; // 使用 Player player; CareTaker taker; taker.setMemento(player.createMemento()); player.setMemento(taker.getMemento()); 观察者模式 **************************************** 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 .. code-block:: cpp class Subject; class Observer { protected: Subject* sub; public: virtual void update() = 0; }; class Subject { list obs; public: void add(Observer* ob) { obs.push_back(ob); } void del(Observer* ob) { obs.remove(ob); } void onStateChanged() { for (auto ob : obs) { ob->update(); } } }; class BinaryObserver : Observer { public: BinaryObserver(Subject* sub) { sub->add(this); } void update() override { cout << "updated" << endl; } }; //使用 Subject* sub = new Subject; BinaryObserver bin(sub); sub->onStateChanged(); 状态模式 **************************************** .. code-block:: cpp class Context; class State { public: virtual void doAction(Context& context) = 0; }; class Context { State* state = nullptr; public: void setState(State* state) { this->state = state; } State* getState() { return this->state; } }; class StartState : State { public: void doAction(Context& context) override { cout << "Start" << endl; context.setState(this); } }; class EndState : State { public: void doAction(Context& context) override { cout << "End" << endl; context.setState(this); } }; // 使用 Context context; StartState start; start.doAction(context); EndState end; end.doAction(context); 空对象模式 **************************************** 策略模式 **************************************** 策略模式用于将操纵抽象成类,用于减少条件语句的产生。 .. code-block:: cpp struct Strategy { virtual int Op(int num1, int num2) = 0; }; class Plus : Strategy { public: int Op(int num1, int num2) override { return num1 + num2; } }; class Minus : Strategy { public: int Op(int num1, int num2) override { return num1 - num2; } }; // 使用 Plus pl; cout << pl.Op(10, 20) << endl; Minus mi; cout << mi.Op(20, 30) << endl; 模板模式 **************************************** 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。实际上就是使用超类接口操纵子类对象。 访问者模式 **************************************** 在访问者模式(Visitor Pattern)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。 .. image:: assets/访问者模式.png