行为型模式

行为型模式关注于对象之间的通信。

责任链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链路,并沿着这条链传递该请求,直到有一个对象处理它为止。

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);

命令模式

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

class Allocator {
public:
   template <typename T>
   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<Command*> 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<MemeryCommand*>(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();

解释器模式

解释器模式:给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题

迭代器模式

迭代器模式提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

中介者模式

中介者模式是迪米特法则的践行者,通过在复杂系统中引入中介者来简化系统结构。通过引入中介者,将复杂的网状交互转变为更加简单的星状交互。

备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

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());

观察者模式

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

class Subject;

class Observer {
protected:
   Subject* sub;

public:
   virtual void update() = 0;
};

class Subject {
   list<Observer*> 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();

状态模式

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);

空对象模式

策略模式

策略模式用于将操纵抽象成类,用于减少条件语句的产生。

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)中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。

../../_images/访问者模式.png