C++設計模式--觀察者模式
阿新 • • 發佈:2018-12-16
觀察者模式定義了物件之間的一對多依賴,這樣一來,當一個物件改變狀態時,它的所有依賴者都會收到通知並自動更新。
--《Head First》設計模式
圖片來自網路
C++實現觀察者模式:
主題物件:
//weatherdata.h #ifndef __WEATHERDATA_H__ #define __WEATHERDATA_H__ #include <list> #include "currentconditionsdisplay.h" class Observer; //主題物件,負責註冊,刪除,通知觀測者 class Subject { public: Subject(); ~Subject(); virtual void RegisterObserver(Observer* o); virtual void RemoveObserver(Observer* o); virtual void NotifyObserver(); }; class WeatherData : public Subject { public: WeatherData(); virtual ~WeatherData(); void setMeasurements(float temperature,float humidity,float pressure); public: virtual void RegisterObserver(Observer* o) override; virtual void RemoveObserver(Observer* o) override; virtual void NotifyObserver() override; private: void MeasurementsChanged(); private: std::list<Observer*> observers; float m_temperature; float m_humidity; float m_pressure; }; #endif
主題物件實現:
//weatherdata.cc #include "weatherdata.h" Subject::Subject() { } Subject::~Subject() { } void Subject::RegisterObserver(Observer* o) { } void Subject::RemoveObserver(Observer* o) { } void Subject::NotifyObserver() { } WeatherData::WeatherData():Subject() { } WeatherData::~WeatherData() { } void WeatherData::RegisterObserver(Observer* o) { if (o) observers.push_back(o); } void WeatherData::RemoveObserver(Observer* o) { if (o) observers.remove(o); } void WeatherData::NotifyObserver() { for (auto x : observers) x->Update(m_temperature,m_humidity,m_pressure); } void WeatherData::setMeasurements(float temperature, float humidity,float pressure) { m_temperature = temperature; m_humidity = humidity; m_pressure = pressure; //通知觀察者 MeasurementsChanged(); } void WeatherData::MeasurementsChanged() { NotifyObserver(); }
觀察者物件:
//currentconditionsdisplay.h
#ifndef __CURRENTCONDITIONSDISPLAY_H__
#define __CURRENTCONDITIONSDISPLAY_H__
#include "weatherdata.h"
class Subject;
class Observer
{
public:
Observer();
virtual void Update(float temperature,
float humidity,float pressure);
};
class CurrentConditionsDisplay : public Observer
{
public:
CurrentConditionsDisplay(Subject* subject);
virtual void Update(float temperature,
float humidity,float pressure);
private:
void display();
private:
float m_temperature;
float m_humidity;
float m_pressure;
Subject* m_subject;
};
#endif
//currentconditionsdisplay.cc
#include <iostream>
#include "currentconditionsdisplay.h"
Observer::Observer()
{
}
void Observer::Update(float temperature,
float humidity,float pressure)
{
}
CurrentConditionsDisplay
::CurrentConditionsDisplay(Subject* subject)
:m_subject(subject)
{
m_subject->RegisterObserver(this);
}
void CurrentConditionsDisplay::Update(float temperature,
float humidity,float pressure)
{
m_temperature = temperature;
m_humidity = humidity;
m_pressure = pressure;
display();
}
void CurrentConditionsDisplay::display()
{
std::cout << "CurrentConditions : (temperature : " << m_temperature
<< "),(humidity : " << m_humidity << "),(pressure : "<<m_pressure
<<")"<<std::endl;
}
主函式:
//main.cc
#include <unistd.h>
#include "weatherdata.h"
#include "currentconditionsdisplay.h"
int main()
{
WeatherData weatherData;
CurrentConditionsDisplay currentConditionsDisplay(&weatherData);
float temperature = 25.5;
float humidity = 85;
float pressure = 20;
while(true){
weatherData.setMeasurements(temperature++,humidity--,pressure++);
sleep(1);
}
return 0;
}
主函式每隔1秒修改一次主題物件,主題物件更新後通知觀察者。
Linux下編譯:
g++ -std=c++11 -o main main.cc currentconditionsdisplay.cc weatherdata.cc
./main