/* 说明:
报纸出版社 + 订阅者 = 观察者模式
定义:
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
设计原则:
为了交互对象之间的松耦合设计而努力。
*/
/**
* 观察者,即订阅者
*/
class Observer
{
public:
virtual void Update(float temperature, float humidity, float pressure) = 0;
};
/**
* 主题,相当于出版社
*/
class Subject
{
public:
virtual void RegisterObserver(Observer *observer) = 0;
virtual void RemoveObserver(Observer *observer) = 0;
virtual void NotifyObserver() = 0;
};
#include <iostream>
#include <list>
#include "main.h"
class WeatherData : public Subject
{
public:
WeatherData(float temperature=0, float humidity=0, float pressure=0) : _temperature(temperature)
, _humidity(humidity)
, _pressure(pressure)
{}
virtual void RegisterObserver(Observer *observer)
{
_observerList.push_back(observer);
}
virtual void RemoveObserver(Observer *observer)
{
_observerList.remove(observer);
}
/* 主动推送新数据 */
virtual void NotifyObserver()
{
std::list<Observer*>::iterator it = _observerList.begin();
for (; it != _observerList.end(); ++it)
{
(*it)->Update(_temperature, _humidity, _pressure);
}
}
void SetData(float temperature, float humidity, float pressure)
{
_temperature = temperature;
_humidity = humidity;
_pressure = pressure;
MeasurementsChanged();
}
void MeasurementsChanged()
{
NotifyObserver();
}
/* 提供轮询接口,不推介使用 */
float GetTemperature() { return _temperature; }
float GetHumidity() { return _humidity; }
float GetPressure() { return _pressure; }
private:
std::list<Observer*> _observerList;
float _temperature;
float _humidity;
float _pressure;
};
class CurrentConditionDisplay : public Observer
{
public:
CurrentConditionDisplay(Subject *weatherData) : _weatherData(weatherData)
{
_weatherData->RegisterObserver(this);
}
virtual void Update(float temperature, float humidity, float pressure)
{
Display(temperature, humidity, pressure);
}
virtual void Display(float temperature, float humidity, float pressure)
{
std::cout << "Current Condition : " << temperature << " degrees, " << humidity << "% humidity, " << pressure << " pa ." << std::endl;
}
private:
Subject *_weatherData;
};
// class StatisticsDisplay : public Observer, public DisplayElement {};
// class ForecastDisplay : public Observer, public DisplayElement {};
int main()
{
WeatherData weatheData;
CurrentConditionDisplay currDisplay(&weatheData);
weatheData.SetData(23, 10, 1);
return 0;
}