设计模式C++-观察者模式.doc_第1页
设计模式C++-观察者模式.doc_第2页
设计模式C++-观察者模式.doc_第3页
设计模式C++-观察者模式.doc_第4页
设计模式C++-观察者模式.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

精品文档观察者模式,又叫做发布-订阅(Publish/Subscribe)模式观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使得它们能够自动更新自己。观察者模式的动机将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维护一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不方便。而观察者模式的关键对象是主题Subject和观察者Observer,一个Subject可以有任意数目的依赖它的Observer,一旦Subject的状态发生了改变,所有的Observer都可以得到通知。Subject发出通知时并不需要知道谁是它的观察者,也就是说,具体观察者是谁,它根本不需要知道。而任何一个具体观察者不知道也不需要知道其他观察者的存在。什么时候应该使用观察者模式当一个对象的改变需要同时改变其他对象的时候。而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。也可以理解为,当一个抽象模型有两个方面,其中一方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。总的来说,观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。工程结构(1)抽象通知者Subject.h(2)抽象观察者Observer.h(3)具体通知者ConcreteSubject.h(4)具体观察者ConcreteObserver.h(5)客户端类ObserverApp.cpp(1)抽象通知者Subject.hview plaincopy to clipboardprint?/* * description: 主题或者抽象通知者类,一般用一个抽象类或者一个接口实现。 它把所有对观察者对象的引用保存在一个聚集里,每个主题都 可以有任何数量的观察者。抽象主题提供一个接口,可以增加 或者删除观察者对象。 * remark: */ #ifndef _SUBJECT_H_ #define _SUBJECT_H_ #include Observer.h #include #include #include using namespace std; class CSubject public: / 增加观察者 virtual void Attach(CObserver* pObserver) = 0; / 移除观察者 virtual void Detach(CObserver* pObserver) = 0; / 通知 virtual void Notify(void) = 0; ; #endif _SUBJECT_H_ /* * description:主题或者抽象通知者类,一般用一个抽象类或者一个接口实现。 它把所有对观察者对象的引用保存在一个聚集里,每个主题都 可以有任何数量的观察者。抽象主题提供一个接口,可以增加 或者删除观察者对象。 * remark:*/#ifndef _SUBJECT_H_#define _SUBJECT_H_#include Observer.h#include #include #include using namespace std;class CSubjectpublic: / 增加观察者 virtual void Attach(CObserver* pObserver) = 0; / 移除观察者 virtual void Detach(CObserver* pObserver) = 0; / 通知 virtual void Notify(void) = 0; ;#endif _SUBJECT_H_ (2)抽象观察者Observer.hview plaincopy to clipboardprint?/* * description: 抽象观察者类,为所有的具体观察者定义一个接口,在得到主题 的通知时更新自己 * remark: */ #ifndef _OBSERVER_H_ #define _OBSERVER_H_ class CObserver public: virtual void Update() = 0; ; #endif _OBSERVER_H_ /* * description:抽象观察者类,为所有的具体观察者定义一个接口,在得到主题 的通知时更新自己 * remark:*/#ifndef _OBSERVER_H_#define _OBSERVER_H_class CObserverpublic: virtual void Update() = 0;#endif _OBSERVER_H_ (3)具体通知者ConcreteSubject.hview plaincopy to clipboardprint?/* * description: 具体主题类或者具体通知者,将有关状态存入具体观察者对象;在 具体主题的内部状态改变时,给所有登记过的观察者发出通知。 * remark: */ #ifndef _CONCRETE_SUBJECT_H_ #define _CONCRETE_SUBJECT_H_ #include Subject.h class CConcreteSubject : public CSubject public: / 增加观察者 void Attach(CObserver* pObserver) m_listObservers.push_back(pObserver); / 移除观察者 void Detach(CObserver* pObserver) m_listObservers.remove(pObserver); / 通知 void Notify(void) list:iterator lIter; for (lIter = m_listObservers.begin(); lIter != m_listObservers.end(); lIter+) (*lIter)-Update(); void SetState(const string& strState) m_strSubjectState = strState; string GetState(void) return m_strSubjectState; private: string m_strSubjectState; list m_listObservers; ; #endif _CONCRETE_SUBJECT_H_ /* * description:具体主题类或者具体通知者,将有关状态存入具体观察者对象;在 具体主题的内部状态改变时,给所有登记过的观察者发出通知。 * remark:*/#ifndef _CONCRETE_SUBJECT_H_#define _CONCRETE_SUBJECT_H_#include Subject.hclass CConcreteSubject : public CSubjectpublic: / 增加观察者 void Attach(CObserver* pObserver) m_listObservers.push_back(pObserver); / 移除观察者 void Detach(CObserver* pObserver) m_listObservers.remove(pObserver); / 通知 void Notify(void) list:iterator lIter; for (lIter = m_listObservers.begin(); lIter != m_listObservers.end(); lIter+) (*lIter)-Update(); void SetState(const string& strState) m_strSubjectState = strState; string GetState(void) return m_strSubjectState; private: string m_strSubjectState; list m_listObservers;#endif _CONCRETE_SUBJECT_H_ (4)具体观察者ConcreteObserver.hview plaincopy to clipboardprint?/* * description: 具体观察者,实现抽象观察者角色所要求的更新接口,以便使本 身的状态与主题的状态相协调。具体观察者角色可以保存一个指 向具体主题对象的引用 * remark: */ #ifndef _CONCRETE_OBSERVER_H_ #define _CONCRETE_OBSERVER_H_ #include ConcreteSubject.h class CConcreteObserver : public CObserver public: CConcreteObserver(CConcreteSubject* pSubject, const string& strName) m_pSubject = pSubject; m_strName = strName; void Update(void) if (NULL != m_pSubject) m_strObserverState = m_pSubject-GetState(); cout 观察者【 m_strName 】的新通知: m_strObserverState GetState(); cout 观察者【 m_strName 】的新通知: m_strObserverState Attach(pConcreteObserver1); pConcreteSubject-Attach(pConcreteObserver2); pConcreteSubject-Attach(pConcreteObserver3); pConcreteSubject-Detach(pConcreteObserver3); pConcreteSubject-SetState(快休息); pConcreteSubject-Notify(); system(pause); FreeMemory(pConcreteObserver1); FreeMemory(pConcreteObserver2); FreeMemory(pConcreteObserver3); FreeMemory(pConcreteSubject); return 0; / ObserverApp.cpp : 定义控制台应用程序的入口点。#include stdafx.h#include ConcreteSubject.h#include ConcreteObserver.hvoid FreeMemory(void* Pointer) if (NULL != Pointer) free(Pointer); int _tmain(int argc, _TCHAR* argv) CConcreteSubject* pConcreteSubject = NULL; pConcreteSubject = new CConcreteSubject(); CConcreteObserver* pConcreteObserver1 = NULL; pConcreteObserver1 = new CConcreteObserver(pConcreteSubject, Alice); CConcreteObserver* pConcreteObserver2 = NULL; pConcreteObserver2 = new CConcreteObserver(pConcreteSubject, Bob); CConcreteObserver* pConcreteObserver3 = NULL; pConcreteObserver3 = new CConcreteObserver(pConcreteSubject, Carey); pConcreteSubject-Attach(pConcreteObserver1); pConcreteSubject-Attach(pConcreteObserver2); pConcreteSubject-Attach(pConcreteObserver3); pConcreteSubject-Detach(pConcreteObserver3); pConcreteSubject-SetState(快休息); pConcreteSubject-Notify(); system(pause); FreeMemory(pConcreteObserver1); FreeMemory(pConcreteObserver2); FreeMemory(pConcreteObserver3); FreeMemory(pConcreteSubject);return 0;观察者模式的不足尽管已经用了依赖倒转原则,但是“抽象通知者”还是依赖“抽象观察者”,也就是说,万一没有了抽象观察者这样的接口,通知的功能就完成不了。另外每个具体观察者,它不一定是“更新”的方法要调用。比如:我们的VS开发工具,当我们调式程序时,希望是“工具箱”隐藏,“自动窗口”打开,这根本就不是同名的方法。这就是不足的地方。如果通知者和观察者之间根本就相互不知道,由客户端来决定通知谁。事件委托:委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看做是对函数的抽象,是函数的“类”,委托的实例将代表一个具体的函数。一个委托可以搭载多个方法,所有方法被依次唤起。可以使得委托对象所搭载的方法并不需要属于同一个类。委托对象所搭载的所有方法必须具有相同的原型和形式,也就是拥有相同的参数列表和返回值类型。工程结构(1)通知者类(2)观察者类(3)客户端类(1)通知者类view plaincopy to clipboardprint?/* * description: 具体主题类或者具体通知者,将有关状态存入具体观察者对象;在 具体主题的内部状态改变时,给所有登记过的观察者发出通知。 * remark: */ #ifndef _CONCRETE_SUBJECT_H_ #define _CONCRETE_SUBJECT_H_ #include using namespace std; class Observer; class CSubject public: void AddObserver(Observer* pOb, void (Observer:*pMemFunc)() m_MapOb.insert(pair(pOb, pMemFunc); void Notify(void) ObIter Iter = m_MapOb.begin(); for (; Iter != m_MapOb.end(); Iter+) void (Observer:*pMemFunc)() = Iter-second; (Iter-first-*pMemFunc)(); string GetSubject(void) return m_strSubject; void SetSubject(const string& strSubject) m_strSubject = strSubject; private: map m_MapOb; typedef map:iterator ObIter; string m_strSubject; ; #endif _CONCRETE_SUBJECT_H_ /* * description:具体主题类或者具体通知者,将有关状态存入具体观察者对象;在 具体主题的内部状态改变时,给所有登记过的观察者发出通知。 * remark:*/#ifndef _CONCRETE_SUBJECT_H_#define _CONCRETE_SUBJECT_H_#include using namespace std;class Observer;class CSubjectpublic: void AddObserver(Observer* pOb, void (Observer:*pMemFunc)() m_MapOb.insert(pair(pOb, pMemFunc); void Notify(void) ObIter Iter = m_MapOb.begin(); for (; Iter != m_MapOb.end(); Iter+) void (Observer:*pMemFunc)() = Iter-second; (Iter-first-*pMemFunc)(); string GetSubject(void) return m_strSubject; void SetSubject(const string& strSubject) m_strSubject = strSubject; private: map m_MapOb; typedef map:iterator ObIter; string m_strSubject;#endif _CONCRETE_SUBJECT_H_ (2)观察者类view plaincopy to clipboardprint?/* * description: * remark: */ #ifndef _CONCRETE_OBSERVER_H_ #define _CONCRETE_OBSERVER_H_ #include #include using namespace std; class Observer / do nothing ; class CSubject; class CObserverA : public Observer public: CObserverA(const string& strName, CSubject* pSubject) m_strName = strName; m_pSubject = pSubject; void UpdateOfObserverA(void) if (NULL != m_pSubject) cout GetSubject() m_strName 别打魔兽争霸了 endl; private: string m_strName; CSubject* m_pSubject; ; class CObserverB : public Observer public: CObserverB(const string& strName, CSubject* pSubject) m_strName = strName; m_pSubject = pSubject; void UpdateOfObserverB(void) if (NULL != m_pSubject) cout GetSubject() m_strName 别打魔兽世界了 endl; private: string m_strName; CSubject* m_pSubject; ; #endif _CONCRETE_OBSERVER_H_ /* * description: * remark:*/#ifndef _CONCRETE_OBSERVER_H_#define _CONCRETE_OBSERVER_H_#include #include using namespace std;class Observer / do nothing;class CSubject;class CObserverA : public Observerpublic: CObserverA(const string& strName, CSubject* pSubject) m_strName = strName; m_pSubject = pSubject; void UpdateOfObserverA(void) if (NULL != m_pSubject) cout GetSubject() m_strName 别打魔兽争霸了 endl; private: string m_strName; CSubject* m_pSubject;class CObserverB : public Observerpublic: CObserverB(const string& s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论