设计模式C++观察者模式.docx
- 文档编号:3217353
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:25
- 大小:19.19KB
设计模式C++观察者模式.docx
《设计模式C++观察者模式.docx》由会员分享,可在线阅读,更多相关《设计模式C++观察者模式.docx(25页珍藏版)》请在冰点文库上搜索。
设计模式C++观察者模式
观察者模式,又叫做发布-订阅(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.h
viewplaincopytoclipboardprint?
/************************************************************************
*description:
主题或者抽象通知者类,一般用一个抽象类或者一个接口实现。
它把所有对观察者对象的引用保存在一个聚集里,每个主题都
可以有任何数量的观察者。
抽象主题提供一个接口,可以增加
或者删除观察者对象。
*remark:
************************************************************************/
#ifndef_SUBJECT_H_
#define_SUBJECT_H_
#include"Observer.h"
#include
#include
#include
usingnamespacestd;
classCSubject
{
public:
//增加观察者
virtualvoidAttach(CObserver*pObserver)=0;
//移除观察者
virtualvoidDetach(CObserver*pObserver)=0;
//通知
virtualvoidNotify(void)=0;
};
#endif_SUBJECT_H_
/************************************************************************
*description:
主题或者抽象通知者类,一般用一个抽象类或者一个接口实现。
它把所有对观察者对象的引用保存在一个聚集里,每个主题都
可以有任何数量的观察者。
抽象主题提供一个接口,可以增加
或者删除观察者对象。
*remark:
************************************************************************/
#ifndef_SUBJECT_H_
#define_SUBJECT_H_
#include"Observer.h"
#include
#include
#include
usingnamespacestd;
classCSubject
{
public:
//增加观察者
virtualvoidAttach(CObserver*pObserver)=0;
//移除观察者
virtualvoidDetach(CObserver*pObserver)=0;
//通知
virtualvoidNotify(void)=0;
};
#endif_SUBJECT_H_
(2)抽象观察者Observer.h
viewplaincopytoclipboardprint?
/************************************************************************
*description:
抽象观察者类,为所有的具体观察者定义一个接口,在得到主题
的通知时更新自己
*remark:
************************************************************************/
#ifndef_OBSERVER_H_
#define_OBSERVER_H_
classCObserver
{
public:
virtualvoidUpdate()=0;
};
#endif_OBSERVER_H_
/************************************************************************
*description:
抽象观察者类,为所有的具体观察者定义一个接口,在得到主题
的通知时更新自己
*remark:
************************************************************************/
#ifndef_OBSERVER_H_
#define_OBSERVER_H_
classCObserver
{
public:
virtualvoidUpdate()=0;
};
#endif_OBSERVER_H_
(3)具体通知者ConcreteSubject.h
viewplaincopytoclipboardprint?
/************************************************************************
*description:
具体主题类或者具体通知者,将有关状态存入具体观察者对象;在
具体主题的内部状态改变时,给所有登记过的观察者发出通知。
*remark:
************************************************************************/
#ifndef_CONCRETE_SUBJECT_H_
#define_CONCRETE_SUBJECT_H_
#include"Subject.h"
classCConcreteSubject:
publicCSubject
{
public:
//增加观察者
voidAttach(CObserver*pObserver)
{
m_listObservers.push_back(pObserver);
}
//移除观察者
voidDetach(CObserver*pObserver)
{
m_listObservers.remove(pObserver);
}
//通知
voidNotify(void)
{
list
:
iteratorlIter;
for(lIter=m_listObservers.begin();lIter!
=m_listObservers.end();lIter++)
{
(*lIter)->Update();
}
}
voidSetState(conststring&strState)
{
m_strSubjectState=strState;
}
stringGetState(void)
{
returnm_strSubjectState;
}
private:
stringm_strSubjectState;
list
};
#endif_CONCRETE_SUBJECT_H_
/************************************************************************
*description:
具体主题类或者具体通知者,将有关状态存入具体观察者对象;在
具体主题的内部状态改变时,给所有登记过的观察者发出通知。
*remark:
************************************************************************/
#ifndef_CONCRETE_SUBJECT_H_
#define_CONCRETE_SUBJECT_H_
#include"Subject.h"
classCConcreteSubject:
publicCSubject
{
public:
//增加观察者
voidAttach(CObserver*pObserver)
{
m_listObservers.push_back(pObserver);
}
//移除观察者
voidDetach(CObserver*pObserver)
{
m_listObservers.remove(pObserver);
}
//通知
voidNotify(void)
{
list
:
iteratorlIter;
for(lIter=m_listObservers.begin();lIter!
=m_listObservers.end();lIter++)
{
(*lIter)->Update();
}
}
voidSetState(conststring&strState)
{
m_strSubjectState=strState;
}
stringGetState(void)
{
returnm_strSubjectState;
}
private:
stringm_strSubjectState;
list
};
#endif_CONCRETE_SUBJECT_H_
(4)具体观察者ConcreteObserver.h
viewplaincopytoclipboardprint?
/************************************************************************
*description:
具体观察者,实现抽象观察者角色所要求的更新接口,以便使本
身的状态与主题的状态相协调。
具体观察者角色可以保存一个指
向具体主题对象的引用
*remark:
************************************************************************/
#ifndef_CONCRETE_OBSERVER_H_
#define_CONCRETE_OBSERVER_H_
#include"ConcreteSubject.h"
classCConcreteObserver:
publicCObserver
{
public:
CConcreteObserver(CConcreteSubject*pSubject,conststring&strName)
{
m_pSubject=pSubject;
m_strName=strName;
}
voidUpdate(void)
{
if(NULL!
=m_pSubject)
{
m_strObserverState=m_pSubject->GetState();
cout<<"观察者【"< "< } } CConcreteSubject*GetSubject(void) { returnm_pSubject; } voidSetSubject(CConcreteSubject*pSubject) { m_pSubject=pSubject; } private: stringm_strName; stringm_strObserverState; CConcreteSubject*m_pSubject; }; #endif_CONCRETE_OBSERVER_H_ /************************************************************************ *description: 具体观察者,实现抽象观察者角色所要求的更新接口,以便使本 身的状态与主题的状态相协调。 具体观察者角色可以保存一个指 向具体主题对象的引用 *remark: ************************************************************************/ #ifndef_CONCRETE_OBSERVER_H_ #define_CONCRETE_OBSERVER_H_ #include"ConcreteSubject.h" classCConcreteObserver: publicCObserver { public: CConcreteObserver(CConcreteSubject*pSubject,conststring&strName) { m_pSubject=pSubject; m_strName=strName; } voidUpdate(void) { if(NULL! =m_pSubject) { m_strObserverState=m_pSubject->GetState(); cout<<"观察者【"< "< } } CConcreteSubject*GetSubject(void) { returnm_pSubject; } voidSetSubject(CConcreteSubject*pSubject) { m_pSubject=pSubject; } private: stringm_strName; stringm_strObserverState; CConcreteSubject*m_pSubject; }; #endif_CONCRETE_OBSERVER_H_ (5)客户端类ObserverApp.cpp viewplaincopytoclipboardprint? //ObserverApp.cpp: 定义控制台应用程序的入口点。 // #include"stdafx.h" #include"ConcreteSubject.h" #include"ConcreteObserver.h" voidFreeMemory(void*Pointer) { if(NULL! =Pointer) { free(Pointer); } } int_tmain(intargc,_TCHAR*argv[]) { CConcreteSubject*pConcreteSubject=NULL; pConcreteSubject=newCConcreteSubject(); CConcreteObserver*pConcreteObserver1=NULL; pConcreteObserver1=newCConcreteObserver(pConcreteSubject,"Alice"); CConcreteObserver*pConcreteObserver2=NULL; pConcreteObserver2=newCConcreteObserver(pConcreteSubject,"Bob"); CConcreteObserver*pConcreteObserver3=NULL; pConcreteObserver3=newCConcreteObserver(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); return0; } //ObserverApp.cpp: 定义控制台应用程序的入口点。 #include"stdafx.h" #include"ConcreteSubject.h" #include"ConcreteObserver.h" voidFreeMemory(void*Pointer) { if(NULL! =Pointer) { free(Pointer); } } int_tmain(intargc,_TCHAR*argv[]) { CConcreteSubject*pConcreteSubject=NULL; pConcreteSubject=newCConcreteSubject(); CConcreteObserver*pConcreteObserver1=NULL; pConcreteObserver1=newCConcreteObserver(pConcreteSubject,"Alice"); CConcreteObserver*pConcreteObserver2=NULL; pConcreteObserver2=newCConcreteObserver(pConcreteSubject,"Bob"); CConcreteObserver*pConcreteObserver3=NULL; pConcreteObserver3=newCConcreteObserver(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); return0; } 观察者模式的不足 尽管已经用了依赖倒转原则,但是“抽象通知者”还是依赖“抽象观察者”,也就是说,万一没有了抽象观察者这样的接口,通知的功能就完成不了。 另外每个具体观察者,它不一定是“更新”的方法要调用。 比如: 我们的VS开发工具,当我们调式程序时,希望是“工具箱”隐藏,“自动窗口”打开,这根本就不是同名的方法。 这就是不足的地方。 如果通知者和观察者之间根本就相互不知道,由客户端来决定通知谁。 事件委托: 委托就是一种引用方法的类型。 一旦为委托分配了方法,委托将与该方法具有完全相同的行为。 委托方法的使用可以像其他任何方法一样,具有参数和返回值。 委托可以看做是对函数的抽象,是函数的“类”,委托的实例将代表一个具体的函数。 一个委托可以搭载多个方法,所有方法被依次唤起。 可以使得委托对象所搭载的方法并不需要属于同一个类。 委托对象所搭载的所有方法必须具有相同的原型和形式,也就是拥有相同的参数列表和返回值类型。 工程结构 (1)通知者类 (2)观察者类 (3)客户端类 (1)通知者类 viewplaincopytoclipboardprint? /************************************************************************ *description: 具
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 设计 模式 C+ 观察者