- 浏览: 353498 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (335)
- C++ (190)
- 设计模式 (43)
- 数据库技术 (5)
- 网络编程 (11)
- 自动化测试 (6)
- Linux (13)
- OpenSSL (10)
- MS Crypt API (5)
- SCM (2)
- English (4)
- Android (10)
- EMV规范 (1)
- Saturn Platform (0)
- C (10)
- SQL (2)
- ASP.NET (3)
- 英语口语学习 (3)
- 调试工具 (21)
- 编译技术 (5)
- UML (1)
- 项目管理 (5)
- 敏捷开发 (2)
- Http Server (6)
- 代码审查、代码分析 (5)
- 面试基础 (10)
- 重点知识 (16)
- STL (6)
- Efficient C++资料 (8)
- 数据结构和算法 (7)
- 读书笔记 (0)
- 开源项目 (4)
- 多线程 (2)
- Console App (6)
- 个人开源项目 (4)
- IBM DevelopWorks (4)
- Java (16)
- 内存泄漏相关调试和检测 (13)
- 软件测试相关技术 (2)
- C# (11)
- Apple Related (1)
- 软件测试和管理 (2)
- EMV (1)
- Python (1)
- Node.js (6)
- JavaScript (5)
- VUE (1)
- Frontend (1)
- Backend (4)
- RESTful API (3)
- Firebase (3)
最新评论
-
u013189503:
来个密码吧
[C++][Logging] 项目中写日志模块的实现 -
wyf_vc:
来个密码啊!!
[C++][Logging] 项目中写日志模块的实现
1 定义:
观察者模式(有时又被称为发布/订阅模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。
定义对象间的一种一对多的以来关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
别名:依赖(Dependennts),发布-订阅(Publish-Subscribe)
2 设计原则
为了交互对象之间的松耦合设计而努力,简单点讲就是出版者+订阅者=观察者模式。
3 参与类别
参与本模式的各类别列出如下。成员函式以模拟的方式列出。
3.1 抽象目标类别
此抽象类别提供一个接口让观察者进行添附与解附作业。此类别内有个不公开的观察者串炼,并透过下列函式(方法)进行作业
添附(Attach):新增观察者到串炼内,以追踪目标物件的变化。
解附(Detach):将已经存在的观察者从串炼中移除。
通知(Notify):利用观察者所提供的更新函式来通知此目标已经产生变化。
添附函式包涵了一个观察者物件参数。也许是观察者类别的虚拟函式(即更新函式),或是在非面向对象的设定中所使用的函式指标(更广泛来讲,函式子或是函式物件)。
3.2 目标类别
此类别提供了观察者欲追踪的状态。也利用其源类别(例如前述的抽象目标类别)所提供的方法,来通知所有的观察者其状态已经更新。此类别拥有以下函式
取得状态(GetState):回传该目标物件的状态。
3.3 抽象观察者接口
抽象观察者类别是一个必须被实做的抽象类别。这个类别定义了所有观察者都拥有的更新用接口,此接口是用来接收目标类别所发出的更新通知。此类别含有以下函式
更新(Update):会被实做的一个抽象(虚拟)函式。
3.4 观察者类别
这个类别含有指向目标类别的参考(reference),以接收来自目标类别的更新状态。此类别含有以下函式
更新(Update):是前述抽象函式的实做。当这个函式被目标物件呼叫时,观察者物件将会呼叫目标物件的取得状态函式,来其所拥有的更新目标物件资讯。
每个观察者类别都要实做它自己的更新函式,以应对状态更新的情形。
当目标物件改变时,会通过呼叫它自己的通知函式来将通知送给每一个观察者物件,这个通知函式则会去呼叫已经添附在串炼内的观察者更新函式。通知与更新函式可能会有一些参数,好指明是目前目标物件内的何种改变。这么作将可增进观察者的效率(只更新那些改变部份的状态)。
4 观察者模式的优点
观察者与被观察者之间是属于轻度的关联关系,并且是抽象耦合的,这样,对于两者来说都比较容易进行扩展。
观察者模式是一种常用的触发机制,它形成一条触发链,依次对各个观察者的方法进行处理。但同时,这也算是观察者模式一个缺点,由于是链式触发,当观察者比较多的时候,性能问题是比较令人担忧的。并且,在链式结构中,比较容易出现循环引用的错误,造成系统假死。
观察者模式(有时又被称为发布/订阅模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。
定义对象间的一种一对多的以来关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
别名:依赖(Dependennts),发布-订阅(Publish-Subscribe)
2 设计原则
为了交互对象之间的松耦合设计而努力,简单点讲就是出版者+订阅者=观察者模式。
3 参与类别
参与本模式的各类别列出如下。成员函式以模拟的方式列出。
3.1 抽象目标类别
此抽象类别提供一个接口让观察者进行添附与解附作业。此类别内有个不公开的观察者串炼,并透过下列函式(方法)进行作业
添附(Attach):新增观察者到串炼内,以追踪目标物件的变化。
解附(Detach):将已经存在的观察者从串炼中移除。
通知(Notify):利用观察者所提供的更新函式来通知此目标已经产生变化。
添附函式包涵了一个观察者物件参数。也许是观察者类别的虚拟函式(即更新函式),或是在非面向对象的设定中所使用的函式指标(更广泛来讲,函式子或是函式物件)。
3.2 目标类别
此类别提供了观察者欲追踪的状态。也利用其源类别(例如前述的抽象目标类别)所提供的方法,来通知所有的观察者其状态已经更新。此类别拥有以下函式
取得状态(GetState):回传该目标物件的状态。
3.3 抽象观察者接口
抽象观察者类别是一个必须被实做的抽象类别。这个类别定义了所有观察者都拥有的更新用接口,此接口是用来接收目标类别所发出的更新通知。此类别含有以下函式
更新(Update):会被实做的一个抽象(虚拟)函式。
3.4 观察者类别
这个类别含有指向目标类别的参考(reference),以接收来自目标类别的更新状态。此类别含有以下函式
更新(Update):是前述抽象函式的实做。当这个函式被目标物件呼叫时,观察者物件将会呼叫目标物件的取得状态函式,来其所拥有的更新目标物件资讯。
每个观察者类别都要实做它自己的更新函式,以应对状态更新的情形。
当目标物件改变时,会通过呼叫它自己的通知函式来将通知送给每一个观察者物件,这个通知函式则会去呼叫已经添附在串炼内的观察者更新函式。通知与更新函式可能会有一些参数,好指明是目前目标物件内的何种改变。这么作将可增进观察者的效率(只更新那些改变部份的状态)。
4 观察者模式的优点
观察者与被观察者之间是属于轻度的关联关系,并且是抽象耦合的,这样,对于两者来说都比较容易进行扩展。
观察者模式是一种常用的触发机制,它形成一条触发链,依次对各个观察者的方法进行处理。但同时,这也算是观察者模式一个缺点,由于是链式触发,当观察者比较多的时候,性能问题是比较令人担忧的。并且,在链式结构中,比较容易出现循环引用的错误,造成系统假死。
#ifndef OBSERVER_H #define OBSERVER_H #include <iostream> #include <list> using namespace std; //观察者模式 namespace Observer { ////////////////////////////////////////////////////////////////////////// class Observer { public: virtual void update(float temp, float humidity, float pressure) = 0; }; ////////////////////////////////////////////////////////////////////////// typedef list<Observer*> ObserverList; class Subject { public: virtual void registerObserver(Observer* ob) = 0 ; virtual void removeObserver(Observer* ob) = 0; virtual void notifyObserver() = 0; }; class WeatherData : public Subject { public: virtual void registerObserver(Observer* ob) { m_ObserverList.push_back(ob); } virtual void removeObserver(Observer* ob) { ObserverList::const_iterator itr = find(ob); if ( itr != m_ObserverList.end() ) { m_ObserverList.erase(itr); } } virtual void notifyObserver() { ObserverList::const_iterator itr = m_ObserverList.begin(); ObserverList::const_iterator end = m_ObserverList.end(); for ( ; itr != end; ++itr) { if ( *itr != NULL) { (*itr)->update(m_Tempperature, m_Humidity, m_Pressure); } } } void measurementsChanged() { notifyObserver(); } void setMeasurements(float tempperature, float humidity, float pressure) { this->m_Tempperature = tempperature; this->m_Humidity = humidity; this->m_Pressure = pressure; measurementsChanged(); } private: ObserverList::const_iterator find( const Observer* ob) { ObserverList::const_iterator itr = m_ObserverList.begin(); ObserverList::const_iterator end = m_ObserverList.end(); for ( ; itr != end; ++itr) { if ( *itr == ob) { return itr; } } return end; } private: ObserverList m_ObserverList; float m_Tempperature; float m_Humidity; float m_Pressure; }; ////////////////////////////////////////////////////////////////////////// class DisplayElement { public: virtual void display() = 0 ; }; ////////////////////////////////////////////////////////////////////////// class CurrentConditionDisplay : public Observer, public DisplayElement { public: CurrentConditionDisplay(Subject* weatherData) : m_Humidity(0), m_Tempperature(0.0f), m_WeatherData(NULL) { if (weatherData != NULL) { if (m_WeatherData!=NULL) { delete m_WeatherData; m_WeatherData = NULL; } this->m_WeatherData = weatherData; this->m_WeatherData->registerObserver(this); } } virtual ~CurrentConditionDisplay() { if (m_WeatherData != NULL) { delete m_WeatherData; m_WeatherData = NULL; } } virtual void update(float temp, float humidity, float pressure) { this->m_Tempperature = temp; this->m_Humidity = humidity; display(); } virtual void display() { cout << "Current conditions: " << m_Tempperature << "F degree and " << m_Humidity << "% humidity" <<endl; } private: float m_Tempperature; float m_Humidity; Subject* m_WeatherData; }; class WeatherStation { public: void run() { WeatherData* weatherData = new WeatherData(); CurrentConditionDisplay* currentDisplay1 = new CurrentConditionDisplay(weatherData); CurrentConditionDisplay* currentDisplay2 = new CurrentConditionDisplay(weatherData); CurrentConditionDisplay* currentDisplay3 = new CurrentConditionDisplay(weatherData); //StatisticsDisplay* statisticsDisplay = new StatisticsDisplay(weatherData); //ForecastDisplay* forecastDisplay = new ForecastDisplay(weatherData); weatherData->setMeasurements(80, 65, 30.4f); weatherData->setMeasurements(82, 70, 29.2f); weatherData->setMeasurements(78, 90, 29.2f); if (weatherData != NULL) { delete weatherData; } if (currentDisplay1 != NULL) { delete currentDisplay1; } if (currentDisplay2 != NULL) { delete currentDisplay2; } if (currentDisplay3 != NULL) { delete currentDisplay3; } } }; }//namespace Observer #endif
- weatherdata.zip (1.1 KB)
- 下载次数: 1
- observer.zip (1.1 KB)
- 下载次数: 0
- _行为模式_head_first_设计模式之观察者模式_observer_.zip (135.2 KB)
- 下载次数: 0
发表评论
-
FreeRTOS
2022-03-05 16:31 204Ref https://blog.csdn.net/weix ... -
串口通讯相关
2018-11-02 13:44 359https://bbs.csdn.net/wap/topics ... -
[转]C++验证IP是否可以PING通
2018-10-30 17:54 1224https://www.cnblogs.com/guoyz13 ... -
C++/MFC 換皮膚
2018-10-20 11:05 422https://blog.csdn.net/u01123991 ... -
WinCE 截屏 - C++ 代碼
2018-08-31 09:45 519// this function create a bmp ... -
Android NDK搭建環境
2017-11-27 13:25 527https://www.cnblogs.com/ut2016- ... -
8583协议相关
2017-10-17 13:38 5128583相关资料,整理中... -
Java高级应用之JNI
2017-06-19 09:00 539参考link http://www.cnblogs.com/l ... -
C++实现ping功能
2017-04-18 11:21 2024基础知识 ping的过程是向目的IP发送一个type=8的I ... -
OpenSSL 编译环境搭建
2017-03-27 15:01 8511 安裝VS2008到 c:\Program Files (x ... -
最优非对称加密填充(OAEP)
2017-03-25 14:53 1506OpenSSL命令---rsautl http://blog. ... -
[Platform Builder] 设置SVM OS build Env
2016-11-10 11:39 01 copy one OSDesign Project to ... -
[Windows] System Error Codes(GetLastError )0-----5999
2016-10-26 13:28 1833ERROR_SUCCESS 0 (0x0) T ... -
开源Windows驱动程序框架
2016-09-17 21:35 811转自 http://code.csdn.net/news/28 ... -
c/c++代码中执行cmd命令
2016-09-14 14:50 1809转自 http://blog.csdn.net/slixinx ... -
C#使用C++标准DLL实例(包含callback)
2016-09-11 19:44 998C++编写标准Win32DLL如下 头文件 /***** ... -
C#调用C++的DLL搜集整理的所有数据类型转换方式
2016-09-09 16:07 924转自 http://www.cnblogs.com/zeroo ... -
WinCE CPU使用率计算 测试工具
2016-09-08 16:14 933转自 http://blog.csdn.net/jan ... -
switch在C++与C#中的一些差异
2016-09-08 15:19 755参考链接 http://blog.csdn.net/weiwe ... -
C++ 鼠标模拟程序
2016-09-04 12:09 1531转自 http://blog.csdn.net/weixinh ...
相关推荐
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。 Observer Pattern defines a one-to-many dependency between objects so that when one object ...
Head.First设计模式_PDF(高清扫描版) 第一部分(共三部分) 在我的资源下可找到其他两部部分 强大的写作阵容。《Head First设计模式》作者Eric Freeman和ElElisabeth Freeman是作家、讲师和技术顾问。Eric拥有耶鲁...
Head First模式设计用的是Java,实现观察者模式使用C++
OOPractice 设计模式项目练习 目录 第一章 模拟鸭子的行为 duck 第二章 观察者模式 observer 第三章 装饰着模式 decorater 第四章 工厂模式 factory 第五章 封装调用 methodinvocation ...《Head First 设计模式》
设计模式观察者模式
java实验: 设计模式(单子、工厂、策略、组合、观察者模式)练习 在上次作业基础上,设计一个贩卖各类书籍的电子商务网站的购物车系统。该系统包括 的模块有: 模块1:图书目录的添加模块,实现对书本信息的增加。 ...
这个工程是《Head First设计模式》书本里面涉及到的例程代码源码 ##1.Strategy(策略模式) 策略设计模式就是定义算法族(接口中定义的方法<也就是对象的行为>),分别进行封装(接口实现类),让他们之间可以相互...
动态控制Page页的Head信息 SubmitOncePage:解决刷新页面造成的数据重复提交问题 SharpRewriter:javascript + xml技术利用#实现url重定向 采用XHTML和CSS设计可重用可换肤的WEB站点 asp.net的网址重定向方法的比较...
#P2P 聊天 此 P2P 聊天已实现为群聊。 聊天是这样实现的: 您必须首先在同一本地服务器中使用聊天。 适应更广泛的方法并不难。 尽管如此,由于测试问题,我... ##Bibliography Head First 设计模式 - O'Reilly Media
观察者模式定义了对象之间一对多的依赖, 这样一来, 当一个对象改变状态 所有依赖都会收到通知, 自动更新 :beer_mug:设计原则1: 为了交互对象之间的松耦合设计而努力 :star:实现细节 自己设计的Observer/Subject: 见 ...
用C++写的一个观察者模式的小Demo,思想来源于Head First
patterns(设计模式)Design Patterns In PythonDesign Patterns Introduction(设计模式介绍)Strategy Pattern(策略模式)实现:design_patterns/strategy.py示例:examples/strategy_example.pyObserver Pattern...