c++设计模式:观察者模式(Observer Pattern)

定义:

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

场景:

我们有一个气象站,我们通过WeatherData获取气象站的最新数据,并更新布告板上的数据。我们定义了两个布告板,一个是温度计,显示最新的温度,另一个布告板就是显示当前的所有温度、湿度和气压的最新数据。

类图:

c++设计模式:观察者模式(Observer Pattern)

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.2fn",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 degreesn",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 设计模式》

原文链接: https://www.cnblogs.com/osyun/archive/2011/11/18/2254376.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    c++设计模式:观察者模式(Observer Pattern)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/36697

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 下午1:27
下一篇 2023年2月8日 下午1:27

相关推荐