设计模式之观察者模式

  观察者模式又称发布-订阅模式,是一种行为型模式。在此种模式中,一个目标物件管理所有相依于它的观察者物件,

  并且在它本身的状态改变时主动发出通知。这种模式通常用来实现事件处理系统。

  观察者模式完美的将观察者和被观察的对象分离开,在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

  观察者模式定义了对象间的一种一对多的依赖关系,以便一个对象状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。

实现方式: 

  观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。实现的时候要注意,

    观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,

    从根本上违反面向对象的设计的原则。无论是观察者“观察”被观察对象,还是被观察对象将自己的改变“通知”观察者,都不应该直接调用。

  比较直观的一种是“注册-通知-撤销注册"的形式。

  

观察者(Observer)将自己注册到被观察对象(Subject),被观察对象将观察者存放在一个容器里,被观察对象发生了某种变化,

  从容器中得到所有注册过的观察者,将变化通知观察者。观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。

  观察者将自己注册到被观察者的容器中,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:

  假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,

  它可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现

观察者模式的适用场景就是一个类发生变化,需要将消息传递到相关很多类的时候。

  1 #include<iostream>
  2 #include<set>
  3 #include<string>
  4 using namespace std;
  5 /////////////////////抽象模式定义
  6 class CObservable;
  7 //观察者,纯虚基类
  8 class CObserver
  9 {
 10 public:
 11 CObserver::CObserver(){};
 12 virtual CObserver::~CObserver(){};
 13 //当被观察的目标发生变化时,通知调用该方法
 14 //来自被观察者pObs,扩展参数为pArg
 15 virtual void Update(CObservable*pObs,void*pArg=NULL)=0;
 16 };
 17 //被观察者,即Subject
 18 class CObservable
 19 {
 20 public:
 21 CObservable():m_bChanged(false){};
 22 virtual~CObservable(){};
 23 //注册观察者
 24 void Attach(CObserver*pObs);
 25 //注销观察者
 26 void Detach(CObserver*pObs);
 27 //注销所有观察者
 28 void DetachAll();
 29 //若状态变化,则遍历观察者,逐个通知更新
 30 void Notify(void*pArg=NULL);
 31 //测试目标状态是否变化
 32 bool HasChanged();
 33 //获取观察者数量
 34 int GetObserversCount();
 35 protected:
 36 //设置状态变化!!!必须继承CObservable才能设置目标状态
 37 void SetChanged();
 38 //初始化目标为未变化状态
 39 void ClearChanged();
 40 private:
 41 boolm_bChanged;//状态
 42 set<CObserver*>m_setObs;//set保证目标唯一性
 43 };
 44 /////////////////////抽象模式实现
 45 void CObservable::Attach(CObserver*pObs)
 46 {
 47 if(!pObs)return;
 48 m_setObs.insert(pObs);
 49 }
 50 void CObservable::Detach(CObserver*pObs)
 51 {
 52 if(!pObs)return;
 53 m_setObs.erase(pObs);
 54 }
 55 void CObservable::DetachAll()
 56 {
 57 m_setObs.clear();
 58 }
 59 void CObservable::SetChanged()
 60 {
 61 m_bChanged=true;
 62 }
 63 void CObservable::ClearChanged()
 64 {
 65 m_bChanged=false;
 66 }
 67 bool CObservable::HasChanged()
 68 {
 69 returnm_bChanged;
 70 }
 71 int CObservable::GetObserversCount()
 72 {
 73 returnm_setObs.size();
 74 }
 75 void CObservable::Notify(void*pArg/*=NULL*/)
 76 {
 77 if(!HasChanged())return;
 78 cout<<"notifyobservers…"<<endl;
 79 ClearChanged();
 80 set<CObserver*>::iteratoritr=m_setObs.begin();
 81 for(;itr!=m_setObs.end();itr++)
 82 {
 83 (*itr)->Update(this,pArg);
 84 }
 85 }
 86 /////////////////////具体应用类定义和实现
 87 //bloger是发布者,即被观察者(subject)
 88 class CBloger:public CObservable
 89 {
 90 public:
 91 void Publish(conststring&strContent)
 92 {
 93 cout<<"blogerpublish,content:"<<strContent<<endl;
 94 SetChanged();
 95 Notify(const_cast<char*>(strContent.c_str()));
 96 }
 97 };
 98 //portal是发布者,即被观察者(subject)
 99 class CPortal:public CObservable
100 {
101 public:
102 void Publish(const string &strContent)
103 {
104 cout<<"portalpublish,content:"<<strContent<<endl;
105 SetChanged();
106 Notify(const_cast<char*>(strContent.c_str()));
107 }
108 };
109 //RSS阅读器,观察者
110 class CRSSReader:public CObserver
111 {
112 public:
113 CRSSReader(conststring&strName):m_strName(strName){}
114 virtual void Update(CObservable *pObs,void *pArg=NULL)
115 {
116 char *pContent=static_cast<char*>(pArg);
117 //观察多个目标
118 if(dynamic_cast<CBloger*>(pObs))
119 {
120 cout<<m_strName<<"updated from bloger,content:"<<pContent<<endl;
121 }
122 elseif(dynamic_cast<CPortal*>(pObs))
123 {
124 cout<<m_strName<<"updated from portal,content:"<<pContent<<endl;
125 }
126 }
127 private:
128 stringm_strName;
129 };
130 //Mail阅读器,观察者
131 class CMailReader:public CObserver
132 {
133 public:
134 CMailReader(conststring &strName):m_strName(strName){}
135 virtual void Update(CObservable *pObs,void *pArg=NULL)
136 {
137 char *pContent=static_cast<char*>(pArg);
138 if(dynamic_cast<CBloger*>(pObs))
139 {
140 cout<<m_strName<<"updated from bloger,content:"<<pContent<<endl;
141 }
142 if(dynamic_cast<CPortal*>(pObs))
143 {
144 cout<<m_strName<<"updated from portal,content:"<<pContent<<endl;
145 }
146 }
147 private:
148 stringm_strName;
149 };
150 /////////////////Main
151 intmain()
152 {
153 //目标(被观察者)
154 CBloger *pBloger=newCBloger();
155 CPortal *pPortal=newCPortal();
156 //观察者.一个观察者可以观察多个目标
157 CRSSReader *pRssReader=new CRSSReader("rssreader");
158 CMailReader *pMailReader=new CMailReader("mailreader");
159 pBloger->Attach(pRssReader);//bloger注册观察者
160 pBloger->Attach(pMailReader);//bloger注册观察者
161 pPortal->Attach(pRssReader);//portal注册观察者
162 pPortal->Attach(pMailReader);//portal注册观察者
163 //博客发布信息
164 pBloger->Publish("博客分享设计模式");
165 cout<<endl;
166 //门户发布信息
167 pPortal->Publish("门户分享设计模式");
168 cout<<"\nportaldetachedmailreader"<<endl;
169 pPortal->Detach(pMailReader);
170 cout<<"portalobserverscount:"<<pPortal->GetObserversCount()<<endl<<endl;
171 pPortal->Publish("门户分享设计模式");
172 system("pause");
173 return0;
174 }
时间: 2024-08-27 03:38:56

设计模式之观察者模式的相关文章

【设计模式】观察者模式

生活中,当某件事发生时,应该通知所有的相关者.例如,上课地点有变,要通知所有学习这门课的同学. 在软件设计中,当一个对象的状态发生变化是,如何通知与它相关的所有对象,就是我们今天要谈到的观察者模式. 观察者模式 概述 定义了一种一对多的依赖关系.让多个观察者对象同事监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有的观察者对象,使它们能够自动更新自己. 实际上,观察者模式所做的工作就是在解除耦合.让耦合的双方都依赖于抽象,而不是依赖于具体.从而使得各自的变化都不会影响另一边的变化. 结

设计模式:观察者模式

设计模式:观察者模式 : http://www.cnblogs.com/li-peng/archive/2013/02/04/2892116.html 观察者模式是我们经常用的一个模式,比如在用wcf做服务的时候通知客户端做一些操作一般用设计者模式. 今天做一个订报纸的小例子来理解一下观察者模式  出版者+订阅者=观察者模式 用下边的图来说就是    人民日报+订阅者=观察者模式 只要是订阅了人民日报的人,有了新报纸就会送到订阅者那里去, 当你不想订的时候取消就不订阅就不会再收到报纸了. //报

设计模式之-观察者模式

该文代码来自设计模式之惮一书. 观察者模式定义: 观察者模式也叫做发布订阅模式. 观察者模式中的角色: 1.被观察者 被观察者职责为管理观察者并通知观察者. 2.观察者 对接受到的消息进行处理. /// <summary> /// 被观察者 /// </summary> public abstract class Subject { /// <summary> /// 观察者集合 /// </summary> private List<IObserva

设计模式(16) 观察者模式(OBSERVER)C++实现

意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 动机: 将一个系统设计成一系列相互协作的类有一个常见的副作用:需要维护相关对象之间的一致性. 观察者模式定义一种交互,即发布-订阅: 一个对象当自身状态发生改变时,会发出通知,但是并不知道谁是他的接收者,但每个接收者都会接收到通知,这些接受者称为观察者. 作为对通知的响应,每个观察者都将查询目标状态,然后改变自身的状态以和目标状态进行同步. 使用场景: 使对象封装为独立的改变和使用:

&lt;&lt;Head First设计模式&gt;&gt;之观察者模式学习

1.概念 定义了对象之间的一对多依赖关系,当一个对象(主题对象)的状态改变时,它的所有依赖者(观察者对象)都会收到通知并自动更新. 2.优势 观察者模式实现了主题对象与观察者对象之间的松耦合,当有新的观察者时,无需修改主题对象的代码,只需要新的观察者对象实现接口.在程序运行的过程中,可以随时注册和删除观察者而不影响主体对象. 观察者模式使主题(Subject)对象和观察者(Observer)对象都可以被轻易地复用. 3.Java中观察者模式 Java API有内置的观察者模式,java.util

大话设计模式_观察者模式(Java代码)

观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们自己能够自动更新自己.简单描述:1个Subject类(可以是抽象类可以是接口),可以有多个具体Subject类(继承抽象Subject),此具体Subject持有多个观察者的引用,在此具体Subject状态发生变化的时候调用这些观察者的相应方法.另外,这些持有的引用是抽象的,不是具体的,而这些引用所指向的对象时具体的观察者(即需要作出更新的具体观察者,这些具体

设计模式-观察者模式(Observer Pattern)

今天看了看观察者模式,有点小小的体会,从以下3点说明之 : 1.看一下经典的观察者模式图 2.讲个故事,说一下逻辑 有一个男人(Subject),他通过一定的手段(attach)拥有了3个女人(Observer):老婆(concreteObserver1),情人(concreteObserver2),小3(concreteObserver3).这3个女人都不知情,但是都想知道男人的月收入情况.而月收入需要通过工资卡(concreteSubject)来体现.所以,每当发工资(setState)时,

常用设计模式之观察者模式 + 事件委托

常用设计模式之观察者模式 + 事件委托 作用及UML (摘自<大话设计模式>) Code 1 abstract class Subject{ 2 protected String state; 3 public void setState(String state){this.state = state;} 4 public String getState(){return this.state;} 5 6 private List<Observer> observers = ne

跟我学设计模式视频教程——观察者模式,迭代器模式

课程视频 观察者模式 迭代器模式 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 跟我学设计模式视频教程--观察者模式,迭代器模式,布布扣,bubuko.com

设计模式之观察者模式C++实现

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. 观察者模式结构图如下: 举例: 气象系统有三个部分分别是气象站(获取实际气象数据的物理装置),WeatherData对象(用来追踪来自气象站的数据,并更新布告板)和布告板(显示目前天气状况给用户看).WeatherData对象知道如何根物理气象站联系,以取得更新信息.WeatherData对象会随机更新三个布告板的显示:目前状况(温度,湿度,气压).气象统计和天气预报.我们的工作是建立一