概要

  在软件构建过程中。我们须要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,全部的依赖对象(观察者对象)都将得到通知。假设这种依赖关系过于紧密,将使软件不能非常好地抵御变化。使用面向对象技术。能够将这种依赖关系弱化,并形成一种稳定的依赖关系。

从而实现软件体系结构的松耦合。

     意图

  定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 全部依赖于它的对象都得到通知并被自己主动更新。[GOF 《设计模式》]

 特点:

        1、  Subject和Observer之间是松偶合的,分别能够各自独立改变。

2、  Subject在发送广播通知的时候,无须指定详细的Observer。Observer能够自己决定是否要订阅Subject的通知。

        3、  遵守大部分GRASP原则和经常使用设计原则,高内聚、低偶合。

应用场景:

        1、  对一个对象状态的更新,须要其它对象同步更新,并且其它对象的数量动态可变。

        2、  对象仅须要将自己的更新通知给其它对象而不须要知道其它对象的细节。

        UML图

       

          代码实现

  1. #pragma once
  2. #include <string>
  3. #include <list>
  4. #include "Define.h"
  5. class IObserver;
  6. class ISubject
  7. {
  8. public:
  9. ISubject(void);
  10. virtual ~ISubject(void);
  11. virtual int Attach(IObserver* pObs) = 0;
  12. virtual int Detach(IObserver* pObs) = 0;
  13. virtual int Notify() = 0;
  14. virtual State GetState() = 0;
  15. virtual void SetState(const State& state) = 0;
  16. protected:
  17. typedef std::list<IObserver*> L_OBS;
  18. L_OBS   m_obsArray;
  19. };
  1. #pragma once
  2. #include "ISubject.h"
  3. class CSubjectA : public ISubject
  4. {
  5. public:
  6. CSubjectA(void);
  7. virtual ~CSubjectA(void);
  8. virtual int Attach(IObserver* pObs);
  9. virtual int Detach(IObserver* pObs);
  10. virtual int Notify();
  11. virtual State GetState();
  12. virtual void SetState(const State& state);
  13. private:
  14. State m_state;
  15. };
  1. #include "CSubjectA.h"
  2. #include "IObserver.h"
  3. CSubjectA::CSubjectA(void)
  4. {
  5. }
  6. CSubjectA::~CSubjectA(void)
  7. {
  8. if (!m_obsArray.empty())
  9. {
  10. m_obsArray.clear();
  11. L_OBS().swap(m_obsArray);
  12. }
  13. }
  14. int CSubjectA::Attach( IObserver* pObs )
  15. {
  16. m_obsArray.push_back(pObs);
  17. return 0;
  18. }
  19. int CSubjectA::Detach( IObserver* pObs )
  20. {
  21. m_obsArray.remove(pObs);
  22. return 0;
  23. }
  24. int CSubjectA::Notify()
  25. {
  26. L_OBS::iterator it_beg, it_end=m_obsArray.end();
  27. for (it_beg=m_obsArray.begin(); it_beg!=it_end; ++it_beg)
  28. {
  29. (*it_beg)->Update();
  30. }
  31. return 0;
  32. }
  33. State CSubjectA::GetState()
  34. {
  35. return m_state;
  36. }
  37. void CSubjectA::SetState( const State& state )
  38. {
  39. m_state = state;
  40. }
  1. #pragma once
  2. #include "Define.h"
  3. class IObserver
  4. {
  5. public:
  6. IObserver(void);
  7. virtual ~IObserver(void);
  8. virtual int Update() = 0;
  9. };
  1. #pragma once
  2. #include "IObserver.h"
  3. class ISubject;
  4. class CObserveA : public IObserver
  5. {
  6. public:
  7. CObserveA(ISubject* pSubject);
  8. virtual ~CObserveA(void);
  9. virtual int Update();
  10. private:
  11. ISubject* m_pSubject;
  12. };
  1. #include "CObserveA.h"
  2. #include <cstdio>
  3. #include "ISubject.h"
  4. CObserveA::CObserveA(ISubject* pSubject)
  5. :m_pSubject(pSubject)
  6. {
  7. m_pSubject->Attach(this);
  8. }
  9. CObserveA::~CObserveA(void)
  10. {
  11. m_pSubject->Detach(this);
  12. }
  13. int CObserveA::Update()
  14. {
  15. State str = m_pSubject->GetState();
  16. printf("first get: [%s]\n", str.c_str());
  17. return 0;
  18. }
  1. #include "CSubjectA.h"
  2. #include "CObserveA.h"
  3. int main()
  4. {
  5. CSubjectA subA;
  6. CObserveA first(&subA);
  7. subA.SetState("test set state");
  8. subA.Notify();
  9. return 0;
  10. }

版权声明:本文博客原创文章。博客,未经同意,不得转载。

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

  1. iOS中MVC等设计模式详解

    iOS中MVC等设计模式详解 在iOS编程,利用设计模式可以大大提高你的开发效率,虽然在编写代码之初你需要花费较大时间把各种业务逻辑封装起来.(事实证明这是值得的!) 模型-视图-控制器(MVC)设计 ...

  2. Cocos观察者设计模式和通报机制

    观察员(Observer)模式也称为公告/订阅(Publish/Subscribe)模式.这是 MVC( 模型-视图-控制器)模型的重要组成部分.天气一直讨论的英国最喜欢的话题,近期天气变化几年已成为 ...

  3. 北京设计模式学习组bjdp.org第7次活动(2013.08.04)回顾会纪要

    时间:2013.08.04,9am-7pm 地点:北京龙泉寺(北京凤凰岭风景区内) 参加人数:北京龙泉寺信息中心(20人).北京设计模式学习组(9人) 活动要点: 1)寺院巡礼:义工师兄带领参观寺院. ...

  4. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  5. java EE设计模式简介

    1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...

  6. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  7. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  8. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  9. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

随机推荐

  1. AssetBundle.CreateFromFile的有趣事情

    有趣的事情发生了: [@MenuItem("AssetBundles/Build AssetBundles")] staticvoid BuildABs () { AssetBun ...

  2. 获取TBitMap图像缓冲区,提高图像处理速度

    使用Dephi进行图像处理可以有多种方法,最常用的应该算是TBitmap,它提供方便的图像存取能力,结合Canvas可进行画线.画圆.图像拷贝等操作.不过在进行大量的图像处理操作时,为了获得更高的速度 ...

  3. 通过崩溃地址找错误行数之Delphi版

    通过崩溃地址找错误行数之Delphi版2009-5-11 17:42:35 来源: 转载 作者:网络 访问:360 次 被顶:2 次 字号:[大 中 小]核心提示:什么是 MAP 文件?简单地讲, M ...

  4. express for node 路由route几种实现方式的思考

    1.路由实现方式和顺序 express框架创建的模板app,js中默认代码 var express = require('express'); var routes = require('./rout ...

  5. POJ 3321 Apple Tree DFS序+fenwick

    题目大意:有一颗长满苹果的苹果树,有两个操作. 1.询问以一个点为根的子树中有多少个苹果. 2.看看一个点有没有苹果,假设没有苹果.那么那里就立即长出一个苹果(= =!):否则就把那个苹果摘下来. 思 ...

  6. alv行可编辑时带出描述

    ALV显示可以编辑的状态下可以带出描述信息等,比如维护表程序输入公司代码时需要带出公司代码的描述,这时就需要通过下面事件来触发 定义一个类: CLASS lcl_event_receiver DEFI ...

  7. uva 1335 - Beijing Guards(二分)

    题目链接:uva 1335 - Beijing Guards 题目大意:有n个人为成一个圈,其中第i个人想要r[i]种不同的礼物,相邻的两个人可以聊天,炫耀自己的礼物.如果两个相邻的人拥有同一种礼物, ...

  8. Zeroonepack coming~^.^

    今天抓的四道DP做完了==三道是用背包做的,突然想起来背包知识点总结还没做~反正时间还早..把01背包和完全背包小结了吧~~福利来啦~~噶呜~ 01背包: 基本思路: 01背包问题是最广为人知的动态规 ...

  9. 一步步学习Linux开发环境搭建与使用

    00.Linux开发环境搭建与使用1--Linux简史 01.Linux开发环境搭建与使用2--Linux系统(ubuntu)安装方案 02.Linux开发环境搭建与使用3--通过虚拟机安装系统(ub ...

  10. C / C++算法学习笔记(7)-双向冒泡

    原始地址:双向冒泡 通常的冒泡是单向的,而这里是双向的,也就是说还要进行反向的工作. 代码看起来复杂,仔细理一下就明白了,是一个来回震荡的方式. 写这段代码的作者认为这样可以在冒泡的基础上减少一些交换 ...