观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
--《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