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