行为型模式关注于对象之间的通信和职责委派

解释器模式

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

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

备忘录模式

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

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

状态模式

状态模式允许对象在更改状态时更改其行为,其主要用于:

  • 用来清除嵌套的条件语句。

  • 用来实现有限状态自动机。

现在假设有一个三相开关。当点击按钮时灯的状态在 Light1, Light2, Off 三种状态切换。即实现下面的状态:

Lamp light;
light.click();    // Light 1
light.click();    // Light 2
light.click();    // Off
light.click();    // Light 1

首先需要一个对象用来储存状态:

class Context {
public:
    void SetStatus(Status* status) {
        delete status_;
        status_ = status;
    }

    Status& GetStatus() {
        return *status_;
    }

private:
    Status* status_;
};

class Lamp {
public:
    Lamp() {
        // 将初始状态设置为 Light1
        ctx_.SetStatus(new Light1(ctx_));
    }
    void click() {
        ctx_.GetStatus().show();
    }

private:
    Context ctx_;
};

然后我们需要一个状态接口:

class Status {
public:
    virtual void show() = 0;
    virtual ~Status()   = default;
};

每当调用 show 时,调用 Context::SetStatus 将当前状态设置为下一个状态:

class Light1 : public Status {
public:
    explicit Light1(Context& ctx) : ctx_(ctx) { }
    void show() override {
        std::cout << "Light1" << std::endl;
        ctx_.SetStatus(new Light2(ctx_));
    }

private:
    Context& ctx_;
};

下面是其余两个状态:

class Off : public Status {
public:
    explicit Off(Context& ctx) : ctx_(ctx) { }
    void show() override {
        std::cout << "Off" << std::endl;
        ctx_.SetStatus(new Light1(ctx_));
    }

private:
    Context& ctx_;
};

class Light2 : public Status {
public:
    explicit Light2(Context& ctx) : ctx_(ctx) { }
    void show() override {
        std::cout << "Light2" << std::endl;
        ctx_.SetStatus(new Off(ctx_));
    }

private:
    Context& ctx_;
};
由于 C++ 在创建对象之前需要先看到对象声明,因此需要将 Off::Show 函数的实现放到最后。

空对象模式

策略模式

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

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)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。实际上就是使用超类接口操纵子类对象。

Last moify: 2024-10-02 08:28:55
Build time:2025-07-18 09:41:42
Powered By asphinx