转自:http://www.jellythink.com/archives/359

前言

之前做了一个性能测试的项目,就是需要对现在的产品进行性能测试,获得测试数据,然后书写测试报告,并提出合理化的改善意见。项目很简单,我们获得了一系列性能测试数据,对于数据,我们需要在Excel中制作测试数据的折线图、饼状图和柱状图,以直观的表现出性能的变化。在实际操作时,我发现,如果我修改了一个数据,折线图、饼状图和柱状图就都发生了变换。这个是如何做到的?这就要说到今天总结的观察者模式了,作为设计模式大家庭中最重要的一个,我们不得不去好好的学习一下观察者模式。

观察者模式

在GOF的《设计模式:可复用面向对象软件的基础》一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化,关注它的对象就会得到通知;这种交互也称为发布-订阅(publish-subscribe)。目标是通知的发布者,它发出通知时并不需要知道谁是它的观察者。

再说说上面的数据和图之间的关系;不管是折线图、饼状图,还是柱状图,它们都依赖于数据;当数据发生变化时,数据对象会通知依赖于它的对象去更新;所以就有了Excel中,当数据发生变化时,对应的统计图也会自动的重绘。

UML类图

Subject(目标)
——目标知道它的观察者。可以有任意多个观察者观察同一个目标;
——提供注册和删除观察者对象的接口。

Observer(观察者)
——为那些在目标发生改变时需获得通知的对象定义一个更新接口。

ConcreteSubject(具体目标)
——将有关状态存入各ConcreteObserver对象;
——当它的状态发生改变时,向它的各个观察者发出通知。

ConcreteObserver(具体观察者)
——维护一个指向ConcreteSubject对象的引用;
——存储有关状态,这些状态应与目标的状态保持一致;
——实现Observer的更新接口以使自身状态与目标的状态保持一致。

观察者模式按照以下方式进行协作:

  1. 当ConcreteSubject发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者;
  2. 在得到一个具体目标的改变通知后,ConcreteObserver对象可向目标对象查询信息。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。

以下是调用时序图:

使用场合

在以下任一情况下都可以使用观察者模式:

  1. 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用;
  2. 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变;
  3. 当一个对象必须通知其它对象,而它又不能假定其它对象是谁;也就是说,你不希望这些对象是紧密耦合的。

代码实现

#include <iostream>
#include <list>
using namespace std; class Observer
{
public:
virtual void Update(int) = 0;
}; class Subject
{
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;
}; class ConcreteObserver : public Observer
{
public:
ConcreteObserver(Subject *pSubject) : m_pSubject(pSubject){} void Update(int value)
{
cout<<"ConcreteObserver get the update. New State:"<<value<<endl;
} private:
Subject *m_pSubject;
}; class ConcreteObserver2 : public Observer
{
public:
ConcreteObserver2(Subject *pSubject) : m_pSubject(pSubject){} void Update(int value)
{
cout<<"ConcreteObserver2 get the update. New State:"<<value<<endl;
} private:
Subject *m_pSubject;
}; class ConcreteSubject : public Subject
{
public:
void Attach(Observer *pObserver);
void Detach(Observer *pObserver);
void Notify(); void SetState(int state)
{
m_iState = state;
} private:
std::list<Observer *> m_ObserverList;
int m_iState;
}; void ConcreteSubject::Attach(Observer *pObserver)
{
m_ObserverList.push_back(pObserver);
} void ConcreteSubject::Detach(Observer *pObserver)
{
m_ObserverList.remove(pObserver);
} void ConcreteSubject::Notify()
{
std::list<Observer *>::iterator it = m_ObserverList.begin();
while (it != m_ObserverList.end())
{
(*it)->Update(m_iState);
++it;
}
} int main()
{
// Create Subject
ConcreteSubject *pSubject = new ConcreteSubject(); // Create Observer
Observer *pObserver = new ConcreteObserver(pSubject);
Observer *pObserver2 = new ConcreteObserver2(pSubject); // Change the state
pSubject->SetState(2); // Register the observer
pSubject->Attach(pObserver);
pSubject->Attach(pObserver2); pSubject->Notify(); // Unregister the observer
pSubject->Detach(pObserver); pSubject->SetState(3);
pSubject->Notify(); delete pObserver;
delete pObserver2;
delete pSubject;
}

总结

观察者模式在23个设计模式中的地位是非常高的,我们基本上各大框架中都是随处可见。真正的理解了整个模式,对我们去理解别人的代码有非常大的帮助;在我们日后的工作中也会或多或少的使用该设计模式。这里总结的不是很全面,在日后如果碰到了需要补充的内容,我会继续补充的;同时也希望大家提出更好的建议。

2014年2月14日 于大连,东软。

(转)C++设计模式——观察者模式的更多相关文章

  1. 18. 星际争霸之php设计模式--观察者模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  2. linkin大话设计模式--观察者模式

    linkin大话设计模式--观察者模式 观察者模式定义了对象间的一对多依赖关系,让一个或者多个观察者观察一个对象主题.当主题对象的状态发生改变的时候,系统能通知所有的依赖于此对象的观察者对象,从而能自 ...

  3. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  4. js设计模式-观察者模式

    定义: 观察者模式又叫发布订阅模式,它定义了对象间的一种一对多的依赖关系.观察者模式让两个对象松耦合地联系在一起,虽然不太清楚彼此的细节,但这不影响他们之间的互相通信. 思路 定义一个对象,在对象中实 ...

  5. 【设计模式】Java设计模式 - 观察者模式

    [设计模式]Java设计模式 - 观察者模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 @一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长 ...

  6. [Head First设计模式]山西面馆中的设计模式——观察者模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 引言 不知不自觉又将设计模式融入生活了,吃个饭也不得安生,也发现生活中的很多场景,都可以用设计模式来模拟.原来设计模式就在 ...

  7. javascript 设计模式-----观察者模式

    观察者模式在设计模式中被重点提到,因为它应用的场景非常多,而且在模块化设计当中扮演着非常重要的角色.MVC模式中最底层的就是观察者模式,当下流行的javascript框架backbone就是很好地运用 ...

  8. c#设计模式-观察者模式

    Observer 与 Subject 互为耦合,但是这种耦合的双方都依赖于抽象,而不依赖于具体. 一.观察者模式 目的 我们都知道解决一个问题有N种解决方式,但在面向对象的设计中如何能做到“高内聚,低 ...

  9. JAVA 设计模式 观察者模式

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

  10. IOS设计模式-观察者模式

    前言:23种软件设计模式中的观察者模式,也是在软件开发中,挺常用的一种设计模式.而在苹果开发中,苹果Cocoa框架已经给我们实现了这个设 计模式,那就是通知和KVO(Key-Value Observi ...

随机推荐

  1. HW4.34

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  2. HDOJ-ACM1071(JAVA) 定积分

    这道题做起来有点无奈,定积分已经忘得差不多了~还可恶的去搜索了抛物线的解析式的求法~哈哈 不过求出来的结果不对...等有时间再去研究这个数学问题吧 - - 以下是JAVA实现: import java ...

  3. httpclient在抓取网页时出现速度慢的情况分析

    问题: 最近在使用httpclient3.0 来做项目,在一台机器部署系统后,发现此机器比其它机器在抓取页面的速度上慢了大概4s,左右. 项目是部署在局域内网,所以代码中都是直接写的IP地址 .在使用 ...

  4. Error message “Assembly must be registered in isolation” when registering Plugins in Microsoft Dynamics CRM 2011 2013 解决办法

    Error message “Assembly must be registered in isolation” when registering Plugins in Microsoft Dynam ...

  5. static与线程安全 -摘自网络

    在.Net中,Static会经常和线程的东西扯在一起.写的代码是不是线程安全呢?好多程序员都在想,不过,有时候随便就放过了.真正出问题的时候再想.其实,如果程序员一开始就明白这里面的机制,也许,编写的 ...

  6. Http协议简单解析及web请求过程

    HTTP协议: HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统. 基于HTTP协议的客户端/服务器请求响应机制的信息交换过程包含下面几个步骤: 1)    ...

  7. Yii2 TimestampBehavior行为

    <?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * ...

  8. UIImageC处理

    UIImageC处理 1.等比缩放 - (UIImage *) scaleImage:(UIImage *)image toScale:(float)scaleSize { UIGraphicsBeg ...

  9. Sigar.jar获取系统信息

    Sigar是Hyperic-hq产品的基础包,是Hyperic HQ主要的数据收集组件. 它用来从许多平台收集系统和处理信息,这些平台包括:Linux, Windows, Solaris, AIX, ...

  10. UVA 185(暴力DFS)

      Roman Numerals  The original system of writing numbers used by the early Romans was simple but cum ...