学习head first,里面使用的是java,我用C++又实现了一遍,只当是记录。
观察者模式强调的是降低类之间的依赖,建立松耦合的关系,是分层设计经常用的方法。分为Subject和Observer, Observer向Subject订阅和取消订阅,原理同定报纸一模一样。当Subject有内容更新的时候直接通知订阅过的Observer。不废话,直接上代码。
//观察者模式
#pragma once
#include <boost/shared_ptr.hpp>
#include <list>
struct WeatherInfo
{
WeatherInfo() : m_iTemperature(0), m_fHumidity(0.0), m_fPressure(0.0)
{
}
int m_iTemperature;
float m_fHumidity;
float m_fPressure;
};
class Observer
{
public:
virtual void update(const WeatherInfo &oWeatherInfo) = 0;
};
typedef boost::shared_ptr<Observer> PTROBSERVER;
class Subject
{
public:
virtual void registerObserver(const PTROBSERVER &ptrObserver) = 0;
virtual void unRegisterObserver(const PTROBSERVER &ptrObserver) = 0;
virtual void notifyObservers() = 0;
};
typedef boost::shared_ptr<Subject> PTRSUBJECT;
class WeatherData : public Subject
{
public:
void registerObserver(const PTROBSERVER &ptrObserver);
void unRegisterObserver(const PTROBSERVER &ptrObserver);
void notifyObservers();
void getWeartherInfo(const WeatherInfo &oWeather);
private:
WeatherInfo m_oWeather;
std::list<PTROBSERVER> m_lstObserver;
};
class wuhan : public Observer
{
public:
void update(const WeatherInfo &oWeatherInfo);
};
class beijing : public Observer
{
public:
void update(const WeatherInfo &oWeatherInfo);
};
class TestObserver
{
public:
static void go();
};
#include "observe.h"
void WeatherData::registerObserver(const PTROBSERVER &ptrObserver)
{
m_lstObserver.push_back(ptrObserver);
}
void WeatherData::unRegisterObserver(const PTROBSERVER &ptrObserver)
{
std::list<PTROBSERVER>::iterator itFind = std::find(m_lstObserver.begin(),
m_lstObserver.end(), ptrObserver);
if (itFind != m_lstObserver.end())
{
m_lstObserver.erase(itFind);
}
}
void WeatherData::notifyObservers()
{
std::list<PTROBSERVER>::const_iterator itNotify = m_lstObserver.begin();
for (; itNotify != m_lstObserver.end(); ++itNotify)
{
const PTROBSERVER &ptrObserver = *itNotify;
ptrObserver->update(m_oWeather);
}
}
void WeatherData::getWeartherInfo(const WeatherInfo &oWeather)
{
m_oWeather = oWeather;
}
void wuhan::update(const WeatherInfo &oWeatherInfo)
{
std::cout << "wuhan weather:" << "Temperature = " << oWeatherInfo.m_iTemperature <<
", Humidity = " << oWeatherInfo.m_fHumidity << ", Pressure = " << oWeatherInfo.m_fPressure << std::endl;
}
void beijing::update(const WeatherInfo &oWeatherInfo)
{
std::cout << "Temperature = " << oWeatherInfo.m_iTemperature <<
", Humidity = " << oWeatherInfo.m_fHumidity << ", Pressure = " << oWeatherInfo.m_fPressure << std::endl;
}
void TestObserver::go()
{
WeatherData oWeather;
PTROBSERVER ptrWuhan(new wuhan);
PTROBSERVER ptrBeijing(new beijing);
oWeather.registerObserver(ptrWuhan);
oWeather.registerObserver(ptrBeijing);
WeatherInfo oInfo;
oInfo.m_iTemperature = 10;
oInfo.m_fHumidity = 1.1;
oInfo.m_fPressure = 2.1;
oWeather.getWeartherInfo(oInfo);
oWeather.notifyObservers();
oWeather.unRegisterObserver(ptrBeijing);
oWeather.notifyObservers();
}