Renbobo's Blog

Wo go where our vision is.

View project on GitHub

观察者模式

27 Aug 2017

以气象站为例: 气象站监控温度,湿度,气压等指标。当温度发生变化时,气象站可以将最新的数据推送给各个显示板。 气象站相当于被观察者,各个显示板相当于观察者。 出版者+订阅者=观察者模式 用户可以注册观察者,也可以注销

观察者模式定义 定义了对象之间一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动更新。

已气象站为例,实现一个将气象站数据变化同步给显示板的代码:

#include <iostream>
#include <vector>
#include <list>
using namespace std;

class Observer;
class Subject{
public:
    Subject(){}
    virtual ~Subject(){}
    void registerObserver(Observer* observer){
        m_observer_list.push_back(observer);
    }
    void deleteObserver(Observer* observer){
        m_observer_list.remove(observer);
    }
    virtual void notifyOberser() = 0;

public:
    list<Observer*> m_observer_list;
};

class WeatherData : public Subject{
public:
    WeatherData(){}
    ~WeatherData(){}
    virtual void notifyOberser(){
        list<Observer*>::iterator iter = m_observer_list.begin();
        for(; iter != m_observer_list.end(); iter++){
            Observer* observer = *iter;
            observer->update(temperature,humidity,pressure);
        }
    }
    void setMeasurements(float temperature,float humidity,float pressure){
        this->m_temperature = temperature;
        this->m_humidity = humidity;
        this->m_pressure = pressure;
        this->notifyOberser();
    }

public:
    float m_temperature;
    float m_humidity;
    float m_pressure;
};

class Observer{
public:
    Observer(){}
    ~Observer(){}
    virtual update(float temperature,float humidity,float pressur) = 0;
};
class Observer1 : public Observer{
public:
    Observer1(WeatherData* weatherData){
        weatherData->registerObserver(this);
        m_temperature = 0;
        m_humidity = 0;
        m_pressure = 0;
    }
    ~Observer1(){}
    void update(float temperature,float humidity,float pressure){
        this->m_temperature = temperature;
        this->m_humidity = humidity;
        this->m_pressure = pressure;
        this->display();
    }
    void display(){
        cout << "Current conditions: " << this->m_temperature
             << "F degrees and " + this->m_humidity << endl;
    }

public:
    WeatherData* m_weatherData;
    float m_temperature;
    float m_humidity;
    float m_pressure;
};

int main(){
    WeatherData* weatherData = new WeatherData();
    Observer* observer = new Observer1(weatherData);

    weatherData->setMeasurements(80,65,30.4f);
    weatherData->setMeasurements(82,70,29.2f);
    weatherData->setMeasurements(79,90,29.2f);

    return 1;
}