观察者模式

2022年 8月 21日 57点热度 0人点赞 0条评论

应用场景

  • Kafka 消息订阅发布是吗?
  • 邮件订阅
  • RSS Feeds

原理

在对象之间定义一个一对多的依赖, 当一个对象状态改变的时候, 所有依赖的对象都会自动收到通知.

观察者模式的实现方法各式各样, 函数, 类的命名等会根据业务场景的不同有很大的差别, 比如 register 函数还可以叫作 attach, remove 函数还可以叫作 detach 等等. 不过, 万变不离其宗, 设计思路都是差不多的.

设计模式要干的事情就是解耦. 创建型模式是将创建和使用代码解耦, 结构型模式是将不同功能代码解耦, 行为型模式是将不同的行为代码解耦, 具体到观察者模式, 它是将观察者和被观察者代码解耦.

代码

#include <iostream>
#include <vector>

using namespace std;

class Observer {
public:

    virtual void update(float temp, float humidity, float pressure) = 0 {};

};

class Subject {
public:

    virtual void registerObserver(Observer* o) = 0 {};
    virtual void removeObserver(Observer* o) = 0 {};
    virtual void notifyObservers() = 0 {};

};

class DisplayElement {
public:
    virtual void display() = 0 {};
};

class WeatherData : public Subject {

private:
    // 使用 vector 来记录观察者
    vector<Observer*> observers;

    float temperature;
    float humidity;
    float pressure;

public:
    WeatherData() {

    }

    void registerObserver(Observer* o) {
        observers.push_back(o);
    }

    void removeObserver(Observer* o) {

        if (observers.empty()) {
            return;
        }

        vector<Observer*>::const_iterator it;

        for (it = observers.begin(); it != observers.end();) {
            if (*it == o) {
                it = observers.erase(it);
            } else {
                ++it;
            }
        }
    }

    /// <summary>
    /// 通知各个观察者
    /// </summary>
    void notifyObservers() {
        if (observers.empty()) {
            return;
        }

        // 通知各个观察者
        for (auto it = observers.begin(); it != observers.end(); ++it) {
            (*it)->update(temperature, humidity, pressure);
        }
    }

    void messurementsChanged() {
        notifyObservers();
    }

    void setMeasurements(float temperature, float humidity, float pressure) {
        this->temperature = temperature;
        this->humidity = humidity;
        this->pressure = pressure;

        messurementsChanged();
    }

};

class CurrentConditionsDisplay : public Observer, public DisplayElement {
private:
    float temperature;
    float humidity;

    Subject* weatherData;

public:

    /// <summary>
    /// 在构造方法中进行注册
    /// </summary>
    /// <param name="weatherData"></param>
    CurrentConditionsDisplay(Subject* weatherData) {
        this->weatherData = weatherData;
        weatherData->registerObserver(this);
    }

    void update(float temperature, float humidity, float pressure) {
        this->temperature = temperature;
        this->humidity = humidity;

        display();
    }

    void display() {
        cout << "Current conditions: " << temperature << "F degrees and " << humidity << "% humidity";
    }
};

int main() {

    WeatherData weatherData;

    CurrentConditionsDisplay currentDisplay(&weatherData);

    weatherData.setMeasurements(80, 65, 30.4f);

    return 0;
}

本文来自:https://blog.duhbb.com

本文链接地址:观察者模式,英雄不问来路,转载请注明出处,谢谢。

有话想说:那就赶紧去给我留言吧。

rainbow

这个人很懒,什么都没留下

文章评论