设计模式之观察者模式
来源:互联网 发布:php 读取docx中的图片 编辑:程序博客网 时间:2024/04/27 05:03
- #include <iostream>
- #include <vector>
- #include <algorithm>
- using namespace std;
- // 预声明观察者接口类
- class Observer;
- // 可观察者接口类
- class Observable
- {
- private:
- bool m_bChanged;
- vector<Observer*> m_vecObsever; // 这里暂时假设不存在重复的观察者
- public:
- // 默认构造函数
- Observable():m_bChanged(false),m_vecObsever(){}
- // 纯虚析构函数
- virtual ~Observable() = 0{}
- // 添加观察者
- void AddObserver(Observer *pObserver)
- {
- vector<Observer*>::const_iterator citer = find(m_vecObsever.begin(), m_vecObsever.end(), pObserver);
- if (citer == m_vecObsever.end())
- {
- m_vecObsever.push_back(pObserver);
- }
- }
- // 删除观察者
- void DeleteObserver(Observer *pObserver)
- {
- vector<Observer*>::const_iterator citer = find(m_vecObsever.begin(), m_vecObsever.end(), pObserver);
- if (citer != m_vecObsever.end())
- {
- m_vecObsever.erase(citer);
- }
- }
- // 通知所有观察者
- void NotifyObservers();
- // 设置状态改变的标志
- void SetChange()
- {
- m_bChanged = true;
- }
- };
- // 天气数据主题类
- class WeatherData:public Observable
- {
- private:
- float m_fTemperature;
- float m_fHumidity;
- float m_fPressure;
- public:
- // 默认构造函数
- WeatherData():m_fTemperature(0.0f),m_fHumidity(0.0f),m_fPressure(0.0f){}
- // 改变测量的参数
- void MeasureChange(float p_fTemperature, float p_fHumidity, float p_fPressure)
- {
- m_fTemperature = p_fTemperature;
- m_fHumidity = p_fHumidity;
- m_fPressure = p_fPressure;
- SetChange();
- NotifyObservers();
- }
- // Getter函数
- float GetTemperature() const
- {
- return m_fTemperature;
- }
- float GetHumidity() const
- {
- return m_fHumidity;
- }
- float GetPressure() const
- {
- return m_fPressure;
- }
- };
- // 观察者接口类
- class Observer
- {
- protected:
- Observable *m_pObservable;
- public:
- // 默认构造函数
- Observer(Observable *p_pObservable):m_pObservable(p_pObservable)
- {
- m_pObservable->AddObserver(this); // 注册此观察者
- }
- // 纯虚析构函数
- virtual ~Observer() = 0
- {
- if (m_pObservable != NULL)
- {
- m_pObservable->DeleteObserver(this); // 注销此观察者
- }
- }
- // 更新
- virtual void Update() = 0;
- // 显示
- virtual void Display() const = 0;
- };
- // 通知所有观察者
- void Observable::NotifyObservers()
- {
- if (m_bChanged)
- {
- for (size_t i = 0; i < m_vecObsever.size(); ++i)
- {
- m_vecObsever[i]->Update();
- }
- m_bChanged = false;
- }
- }
- // 温度公告板
- class TemperatureBoard:public Observer
- {
- private:
- float m_fTemperature;
- public:
- // 默认构造函数
- TemperatureBoard(Observable *p_pObservable):Observer(p_pObservable),m_fTemperature(0.0f){}
- // 更新
- virtual void Update()
- {
- m_fTemperature = (dynamic_cast<WeatherData*> (m_pObservable))->GetTemperature();
- Display();
- }
- // 显示
- virtual void Display() const
- {
- cout << "Current temperature is " << m_fTemperature << "." << endl;
- }
- };
- // 湿度公告板
- class HumidityBoard:public Observer
- {
- private:
- float m_fHumidity;
- public:
- // 默认构造函数
- HumidityBoard(Observable *p_pObservable):Observer(p_pObservable),m_fHumidity(0.0f){}
- // 更新
- virtual void Update()
- {
- m_fHumidity = (dynamic_cast<WeatherData*> (m_pObservable))->GetHumidity();
- Display();
- }
- // 显示
- virtual void Display() const
- {
- cout << "Current humidity is " << m_fHumidity << "." << endl;
- }
- };
- // 压力公告板
- class PressureBoard:public Observer
- {
- private:
- float m_fPressure;
- public:
- // 默认构造函数
- PressureBoard(Observable *p_pObservable):Observer(p_pObservable),m_fPressure(0.0f){}
- // 更新
- virtual void Update()
- {
- m_fPressure = (dynamic_cast<WeatherData*> (m_pObservable))->GetPressure();
- Display();
- }
- // 显示
- virtual void Display() const
- {
- cout << "Current pressure is " << m_fPressure << "." << endl;
- }
- };
- int main()
- {
- // 当前天气数据
- WeatherData weatherData;
- // 公告板
- TemperatureBoard temperatureBoard(&weatherData);
- HumidityBoard humidityBoard(&weatherData);
- PressureBoard pressureBoard(&weatherData);
- weatherData.MeasureChange(23.0f, 80.0f, 60.0f);
- // 注销压力观察者
- weatherData.DeleteObserver(&pressureBoard);
- weatherData.MeasureChange(35.0f, 76.0f, 45.0f);
- system("pause");
- return 0;
- }
对观察者模式的理解:采样针对接口编程的思想保证可观察者和观察者之间的松藕合性,
并使得任何一方的改动都不会导致另一方代码的改变;利用观察者响应接口的一致性和
OO的多态性保证双方都具有很好可移植性.对于可观察者向观察者传递数据方面,可以有
"拉"和"推"两种方式.若使用"拉"的方式,这样可以让各类观察者根据自己的需要各取所需,
但是同时也削弱了可观察者的封装性并在每次扩展可观察者类时都需要添加Getter代码;
而如果采样"推"的方式,则可避免削弱了可观察者的封装性的缺点,虽然概念上传递了所有
状态值,但由于这通常以引用或指针传递方式发生,所以并不带来效率的降低.在本示例程序
中只实现了"拉"的方式.
- 设计模式之-观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- 设计模式之观察者模式
- Head First C# 中文版 图文皆译 第十一章 事件和代理 page505
- 一名大学毕业生的心酸求职历程全记录
- 感冒预防方法
- Head First C# 中文版 图文皆译 第十一章 事件和代理 page506
- 她做了日军倭寇的奸细。
- 设计模式之观察者模式
- 李小龙为了自己的武术,为了证明自己
- 条件组合计算模型
- delphi 读取显示网页上的图片方法
- JavaScript+vml动态生成柱状图
- 妈妈、婆婆都来了【31周】
- Symbian S60真机调试及定位问题
- PHP 压缩文件类
- 采集程序原理,信息采集技术的原理