c++设计模式:观察者模式(Observer Pattern)
2011-11-18 16:58
736 查看
定义:
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
场景:
我们有一个气象站,我们通过WeatherData获取气象站的最新数据,并更新布告板上的数据。我们定义了两个布告板,一个是温度计,显示最新的温度,另一个布告板就是显示当前的所有温度、湿度和气压的最新数据。
类图:
c++代码如下:
运行后结果如下:
Current conditions 123.000F degrees and 456.00% humidity and pressure 789.00
Current conditions 123.00F degrees
Current conditions 789.00F degrees
Current conditions 135.00F degrees
Current conditions 135.00F degrees and 257.00% humidity and pressure 479.00
参考资料:《Head First 设计模式》
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
场景:
我们有一个气象站,我们通过WeatherData获取气象站的最新数据,并更新布告板上的数据。我们定义了两个布告板,一个是温度计,显示最新的温度,另一个布告板就是显示当前的所有温度、湿度和气压的最新数据。
类图:
c++代码如下:
#include <iostream> #include <list> #include <string> #include <algorithm> using namespace std; class Observer; // 主题 class Subject { public: virtual void registerObserver(Observer* o) = 0; virtual void removeObserver(Observer* o) = 0; virtual void notifyObserver() = 0; float getTemperature(); float getHumidity(); float getPressure(); protected: float m_temperature; float m_humidity; float m_pressure; }; // 观察者 class Observer { public: Observer(Subject* pWeaterData); virtual ~Observer() {}; virtual void update() = 0; Subject* getWeaterData(); protected: Subject* m_weaterData; }; class DisplayElement { public: virtual void display() = 0; }; class WeatherData:public Subject { public: WeatherData(); ~WeatherData(); void registerObserver(Observer* o); void removeObserver(Observer* o); void notifyObserver(); void measurementsChanged(); void setMeasurements(float temperature, float humidity, float pressure); private: list<Observer*> m_lObserver; }; // 当前条件显示 class CurrentConditionsDisplay:public Observer,public DisplayElement { public: CurrentConditionsDisplay(Subject* pWeaterData); ~CurrentConditionsDisplay(); void update(); void display(); private: float m_template; // 温度 float m_humidity; // 湿度 float m_pressure; // 气压 }; // 温度计 class Thermometer:public Observer,public DisplayElement { public: Thermometer(Subject* pWeaterData); ~Thermometer(); void update(); void display(); private: float m_template; // 温度 }; float Subject::getTemperature() { return m_temperature; } float Subject::getHumidity() { return m_humidity; } float Subject::getPressure() { return m_pressure; } Observer::Observer(Subject* pWeaterData) { m_weaterData = pWeaterData; } Subject* Observer::getWeaterData() { return m_weaterData; } WeatherData::WeatherData() { m_temperature = 0; m_humidity = 0; m_pressure = 0; } WeatherData::~WeatherData() { list<Observer*>::iterator iter, temp; for (iter=m_lObserver.begin(); iter!=m_lObserver.end(); ++iter) { delete (*iter); } m_lObserver.clear(); } void WeatherData::registerObserver(Observer* o) { m_lObserver.push_back(o); } void WeatherData::removeObserver(Observer* o) { list<Observer*>::iterator iter; iter = std::find(m_lObserver.begin(), m_lObserver.end(), o); if (m_lObserver.end() != iter) { m_lObserver.erase(iter); } } void WeatherData::notifyObserver() { list<Observer*>::iterator iter; for (iter=m_lObserver.begin(); iter!=m_lObserver.end(); ++iter) { (*iter)->update(); } } void WeatherData::measurementsChanged() { notifyObserver(); } void WeatherData::setMeasurements(float temperature, float humidity, float pressure) { m_temperature = temperature; m_humidity = humidity; m_pressure = pressure; measurementsChanged(); } CurrentConditionsDisplay::CurrentConditionsDisplay(Subject* pWeaterData):Observer(pWeaterData) { pWeaterData->registerObserver(this); } CurrentConditionsDisplay::~CurrentConditionsDisplay() { m_weaterData = NULL; } void CurrentConditionsDisplay::update() { m_template = m_weaterData->getTemperature(); m_humidity = m_weaterData->getHumidity(); m_pressure = m_weaterData->getPressure(); display(); } void CurrentConditionsDisplay::display() { printf("Current conditions %f0.2F degrees and %0.2f%s humidity and pressure %0.2f\n",m_template,m_humidity,"%",m_pressure); } Thermometer::Thermometer(Subject* pWeaterData):Observer(pWeaterData) { pWeaterData->registerObserver(this); } Thermometer::~Thermometer() { m_weaterData = NULL; } void Thermometer::update() { m_template = m_weaterData->getTemperature(); display(); } void Thermometer::display() { printf("Current conditions %f0.2F degrees\n",m_template); } int main() { WeatherData* pWeatherData = new WeatherData(); CurrentConditionsDisplay* pCurrentConditionsDisplay = new CurrentConditionsDisplay(pWeatherData); Thermometer* pThermometer = new Thermometer(pWeatherData); pWeatherData->setMeasurements(123,456,789); // 当移除观察者后,需要手动释放内存 pCurrentConditionsDisplay->getWeaterData()->removeObserver(pCurrentConditionsDisplay); pWeatherData->setMeasurements(789,456,123); // 当再次注册后,内存交由主题管理 pCurrentConditionsDisplay->getWeaterData()->registerObserver(pCurrentConditionsDisplay); pWeatherData->setMeasurements(135,257,479); delete pWeatherData; return 0; }
运行后结果如下:
Current conditions 123.000F degrees and 456.00% humidity and pressure 789.00
Current conditions 123.00F degrees
Current conditions 789.00F degrees
Current conditions 135.00F degrees
Current conditions 135.00F degrees and 257.00% humidity and pressure 479.00
参考资料:《Head First 设计模式》
相关文章推荐
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern) (转)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern) (转)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 我理解设计模式C++实现观察者模式Observer Pattern
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- C++设计模式 -> 行为型 -> 观察者模式(Observer Pattern)
- c++设计模式:观察者模式(Observer Pattern)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 我所理解的设计模式(C++实现)——观察者模式(Observer Pattern)
- 设计模式——行为型设计模之借助观察者模式(Observer Pattern)实现模块之间的解耦(四)
- 设计模式总结之Observer Pattern(观察者模式)
- (Boolan)C++设计模式 <四> ——观察者模式(Observer)
- .NET设计模式(19):观察者模式(Observer Pattern)
- c++ 设计模式5 (Observer / Event 观察者模式)