Observer观察者模式
作用:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己

UML图:


Subject类,可翻译为主题或抽象通知者,一般用一个抽象类或者一个借口实现。它把所有对观察者对象的引用保存在一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个借口,可以增加和删除观察者对象。

Observer类,抽象观察者,为所有的具体观察者定义一个借口,在得到主题的通知时更新自己。这个借口叫做更新接口。抽象观察者一般用一个抽象类或者一个接口实现。更新接口通常包含一个Update()方法。

ConcreteSubject类,叫做具体主题或具体通知者,将有关状态存入具体通知者对象;在具体主题的内部状态改变时,给所有等级过的观察者发出通知。通常用一个具体子类实现。

ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。具体观察者角色可以保存一个指向一个具体主题对象的引用。

特点:将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。

何时使用:
当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。

代码如下:

Observer.h

 #ifndef _OBSERVER_H_
#define _OBSERVER_H_ #include <string>
#include <list>
using namespace std; class Subject; class Observer
{
public:
~Observer();
virtual void Update(Subject*)=;
protected:
Observer();
private:
}; class ConcreteObserverA : public Observer
{
public:
ConcreteObserverA();
~ConcreteObserverA();
virtual void Update(Subject*);
protected:
private:
string m_state;
}; class ConcreteObserverB : public Observer
{
public:
ConcreteObserverB();
~ConcreteObserverB();
virtual void Update(Subject*);
protected:
private:
string m_state;
}; class Subject
{
public:
~Subject();
virtual void Notify();
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual string GetState();
virtual void SetState(string state);
protected:
Subject();
private:
string m_state;
list<Observer*> m_lst;
}; class ConcreteSubjectA : public Subject
{
public:
ConcreteSubjectA();
~ConcreteSubjectA();
protected:
private:
}; class ConcreteSubjectB : public Subject
{
public:
ConcreteSubjectB();
~ConcreteSubjectB();
protected:
private:
}; #endif

Observer.cpp

 #include "Observer.h"
#include <iostream>
#include <algorithm> using namespace std; Observer::Observer()
{} Observer::~Observer()
{} ConcreteObserverA::ConcreteObserverA()
{} ConcreteObserverA::~ConcreteObserverA()
{} void ConcreteObserverA::Update(Subject* pSubject)
{
this->m_state = pSubject->GetState();
cout << "The ConcreteObserverA is " << m_state << std::endl;
} ConcreteObserverB::ConcreteObserverB()
{} ConcreteObserverB::~ConcreteObserverB()
{} void ConcreteObserverB::Update(Subject* pSubject)
{
this->m_state = pSubject->GetState();
cout << "The ConcreteObserverB is " << m_state << std::endl;
} Subject::Subject()
{} Subject::~Subject()
{} void Subject::Attach(Observer* pObserver)
{
this->m_lst.push_back(pObserver);
cout << "Attach an Observer\n";
} void Subject::Detach(Observer* pObserver)
{
list<Observer*>::iterator iter;
iter = find(m_lst.begin(),m_lst.end(),pObserver);
if(iter != m_lst.end())
{
m_lst.erase(iter);
}
cout << "Detach an Observer\n";
} void Subject::Notify()
{
list<Observer*>::iterator iter = this->m_lst.begin();
for(;iter != m_lst.end();iter++)
{
(*iter)->Update(this);
}
} string Subject::GetState()
{
return this->m_state;
} void Subject::SetState(string state)
{
this->m_state = state;
} ConcreteSubjectA::ConcreteSubjectA()
{} ConcreteSubjectA::~ConcreteSubjectA()
{} ConcreteSubjectB::ConcreteSubjectB()
{} ConcreteSubjectB::~ConcreteSubjectB()
{}

main.cpp

#include "Observer.h"
#include <iostream> using namespace std; int main()
{
Observer* p1 = new ConcreteObserverA();
Observer* p2 = new ConcreteObserverB();
Observer* p3 = new ConcreteObserverA(); Subject* pSubject = new ConcreteSubjectA();
pSubject->Attach(p1);
pSubject->Attach(p2);
pSubject->Attach(p3); pSubject->SetState("old"); pSubject->Notify(); cout << "-------------------------------------" << endl;
pSubject->SetState("new"); pSubject->Detach(p3);
pSubject->Notify(); return ;
}

结果如下:

C++设计模式-Observer观察者模式的更多相关文章

  1. [C++设计模式]observer 观察者模式

    有这么一种松耦合的需求: 有一些类的对象对类A对象的状态变化非常感兴趣,不会改变类A的对象,也不会被类A的对象改变,想以一种较小的代价观察对类A对象状态变化. 以下的几种方式也能实现上述目的 (1)通 ...

  2. Java 设计模式 – Observer 观察者模式

    目录 [隐藏] 1 代码 1.1 观察者接口: 1.2 被观察者: 1.3 观众类 : 1.4 电影类: 1.5 效果如下: 代码 说明都在注释: 观察者接口: package ObserverMod ...

  3. 委托、事件、Observer观察者模式的使用解析二

    一.设计模式-Observer观察者模式 Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新.Observer模式是一种 ...

  4. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  5. 设计模式之观察者模式(Observable与Observer)

    设计模式之观察者模式(Observable与Observer) 好久没有写博客啦,之前看完了<设计模式之禅>也没有总结一下,现在回忆一下设计模式之观察者模式. 1.什么是观察者模式 简单情 ...

  6. 8.5 GOF设计模式四: 观察者模式Observer

    GOF设计模式四: 观察者模式Observer  现实中遇到的问题  当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式  观察者模式 ...

  7. 设计模式18:Observer 观察者模式(行为型模式)

    Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...

  8. java设计模式解析(1) Observer观察者模式

      设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析( ...

  9. java设计模式之观察者模式

    观察者模式 观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式.模型-视图(View)模式.源-收听者(Listener)模式或从属者模式)是软件设计模式的一种.在此种模 ...

随机推荐

  1. Python检测IP合法 是否为公网IP

    判断IP 格式是否正确 def check_value(self, ipaddr): '''检查IP是否合法 :param ipaddr: string :return True ''' addr=i ...

  2. 前端学习 第七弹: Javascript实现图片的延迟加载

    前端学习 第七弹: Javascript实现图片的延迟加载 为了实现图片进入视野范围才开始加载首先: <img    src="" x-src="/acsascas ...

  3. Google Java编程风格指南

    出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Comm ...

  4. [课程设计]Scrum 1.6 多鱼点餐系统开发进度

    [课程设计]Scrum 1.6 多鱼点餐系统开发进度(点餐页面按钮添加&修复) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4. ...

  5. ExtJs 学习之开篇(三)Ext.grid.Panel表格中的处理

    Ext.grid.Panel Ext.create('Ext.grid.Panel',{        title:'测试表格',        width:400,        height:20 ...

  6. 轻量级Lua IDE ZeroBrane Studio 的使用技巧和汉化

    快捷键 : alt + shift +鼠标 ,可以块选中文本. F12 折叠/展开 所有 F5 调试运行 点击第二次 将跳转到第一个断点处 F10 单步执行 shift +F10 单步执行,不进入函数 ...

  7. linux 安装 python2.7

    若新安装虚拟机,或者新装linux系统.需安装gcc等yum -y install gcc gcc-c++ autoconf automake cmake ntp rsync ssh vim  yum ...

  8. Access 数据库连接 字符串

    <!--Microsoft.Practices.EnterpriseLibrary.Data.dll 操作引用程序集--> <connectionStrings> <ad ...

  9. AFNetwork ATS 网络层改造

    最近一直做项目的ATS改造,期间遇到了种种问题,各种坑都记录下来, 比如iOS版本.afnetwork版本.证书(是否为自签证书).域名验证.TLS版本等等,我们项目更复杂,还使用了域名到IP映射的路 ...

  10. bzoj1553: XOR网络

    Description   计算给定范围内有多少种输入可以使输出为1. 我们假设3 < n < 100, 3 < m < 3000,而且网络中的门是用1到m之间的数任意编号的. ...