观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。它还有两个别名,依赖(Dependents),发布-订阅(Publish-Subsrcibe)。可以举个博客订阅的例子,当博主发表新文章的时候,即博主状态发生了改变,那些订阅的读者就会收到通知,然后进行相应的动作,比如去看文章,或者收藏起来。博主与读者之间存在种一对多的依赖关系。下面给出相应的UML图设计。

可以看到博客类中有一个观察者链表(即订阅者),当博客的状态发生变化时,通过Notify成员函数通知所有的观察者,告诉他们博客的状态更新了。而观察者通过Update成员函数获取博客的状态信息。代码实现不难,下面给出C++的一种实现。

[cpp] view plaincopy print?
  1. //观察者
  2. class Observer
  3. {
  4. public:
  5. Observer() {}
  6. virtual ~Observer() {}
  7. virtual void Update() {}
  8. };
  9. //博客
  10. class Blog
  11. {
  12. public:
  13. Blog() {}
  14. virtual ~Blog() {}
  15. void Attach(Observer *observer) { m_observers.push_back(observer); }     //添加观察者
  16. void Remove(Observer *observer) { m_observers.remove(observer); }        //移除观察者
  17. void Notify() //通知观察者
  18. {
  19. list<Observer*>::iterator iter = m_observers.begin();
  20. for(; iter != m_observers.end(); iter++)
  21. (*iter)->Update();
  22. }
  23. virtual void SetStatus(string s) { m_status = s; } //设置状态
  24. virtual string GetStatus() { return m_status; }    //获得状态
  25. private:
  26. list<Observer* > m_observers; //观察者链表
  27. protected:
  28. string m_status; //状态
  29. };

以上是观察者和博客的基类,定义了通用接口。博客类主要完成观察者的添加、移除、通知操作,设置和获得状态仅仅是一个默认实现。下面给出它们相应的子类实现。

[cpp] view plaincopy print?
  1. //具体博客类
  2. class BlogCSDN : public Blog
  3. {
  4. private:
  5. string m_name; //博主名称
  6. public:
  7. BlogCSDN(string name): m_name(name) {}
  8. ~BlogCSDN() {}
  9. void SetStatus(string s) { m_status = "CSDN通知 : " + m_name + s; } //具体设置状态信息
  10. string GetStatus() { return m_status; }
  11. };
  12. //具体观察者
  13. class ObserverBlog : public Observer
  14. {
  15. private:
  16. string m_name;  //观察者名称
  17. Blog *m_blog;   //观察的博客,当然以链表形式更好,就可以观察多个博客
  18. public:
  19. ObserverBlog(string name,Blog *blog): m_name(name), m_blog(blog) {}
  20. ~ObserverBlog() {}
  21. void Update()  //获得更新状态
  22. {
  23. string status = m_blog->GetStatus();
  24. cout<<m_name<<"-------"<<status<<endl;
  25. }
  26. };

客户的使用方式:

[cpp] view plaincopy print?
  1. //测试案例
  2. int main()
  3. {
  4. Blog *blog = new BlogCSDN("wuzhekai1985");
  5. Observer *observer1 = new ObserverBlog("tutupig", blog);
  6. blog->Attach(observer1);
  7. blog->SetStatus("发表设计模式C++实现(15)——观察者模式");
  8. blog->Notify();
  9. delete blog; delete observer1;
  10. return 0;
  11. }

设计模式C++实现(15)——观察者模式相关推荐

  1. C#设计模式之十六观察者模式(Observer Pattern)【行为型】

    C#设计模式之十六观察者模式(Observer Pattern)[行为型] 原文:C#设计模式之十六观察者模式(Observer Pattern)[行为型] 一.引言 今天是2017年11月份的最后一 ...

  2. php设计模式课程---4、观察者模式的好处是什么

    php设计模式课程---4.观察者模式的好处是什么 一.总结 一句话总结: 方便选择之后去控制监听的板块数:比如选择男士之后,我可以决定监听广告里面的第二和第三板块. 1.为什么有观察者模式? 错误理 ...

  3. Javascript乱弹设计模式系列(1) - 观察者模式(Observer)

    前言 博客园谈设计模式的文章很多,我也受益匪浅,包括TerryLee.吕震宇等等的.NET设计模式系列文章,强烈推荐.对于我,擅长于前台代码的开发,对于设计模式也有一定的了解,于是我想结合Javasc ...

  4. 行为型设计模式(4)—— 观察者模式(Observer Pattern)

    文章目录 1.概述 2.实例 2.1 丑陋的设计 2.2 使用观察者模式 3.应用场景 4.优缺点 5.小结 参考文献 1.概述 使用设计模式可以提高代码的可复用性.可扩充性和可维护性.观察者模式(O ...

  5. 设计模式混编:观察者模式+中介者模式

    针对变化万千的业务需求,采用合适的设计模式是可以轻松应对的. 本文将探索多种优秀设计模式的混编来解决复杂场景的问题,实现1+1>2的效果.应用实践离不开基础,所以文章将以基本概念.设计初衷出发, ...

  6. Unity游戏设计模式(二)观察者模式(Observer Pattern)

    最近看游戏设计模式,当看到观察者模式时被搞得云里雾里的,什么观察者,被观察者,抽象观察者,抽象被观察者.听着这些词就觉得可怕,其实理解以后还是比较简单的. 当我们玩游戏时,经常会出现一些事件,而这个事 ...

  7. 「补课」进行时:设计模式(15)——观察者模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 观察者模式 2.1 定义 观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/subscribe),它是一个在项目中经 ...

  8. 设计模式笔记 18. Observer 观察者模式(行为型模式)

    18. Observer 观察者模式                     2008-09-15 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种"通知依赖关系& ...

  9. 《大话设计模式(C#实现)》(Yanlz+VR云游戏+Unity+SteamVR+云技术+5G+AI+设计模式+GoF+UML+单例模式+观察者模式+抽象工厂+代理模式+框架编程+立钻哥哥++OK+)

    <大话设计模式(C#实现)> 版本 作者 参与者 完成日期 备注 YanlzFramework_GoF_V01_1.0 严立钻 2020.02.10 ##<大话设计模式(C#实现)& ...

  10. 【三】Java 设计模式学习记录:观察者模式

    文章目录 一.观察者模式(行为型模式) 1.1 场景 1.2 普通解决方案 1.3 观察者模式定义 1.4 观察者模式原理 二.代码实现 2.1 代码结构 2.2 上代码 2.3 扩展性 三. 框架应 ...

最新文章

  1. LeetCode 104. Maximum Depth of Binary Tree--二叉树高度--递归或迭代--C++,Python解法
  2. Docker + gunicron + supervisord 部署python应用
  3. MySQL配置文件my.cnf中文版(转载)
  4. Oracle Database 12C 学习之多租户(连载四)
  5. conda 升级_jupyter notebook升级体验!笔记本神器—Jupyter Lab
  6. 分享丨对医学图像分割中的置信度进行量化
  7. caffe linux跑自己数据,caffe+linux平台——跑深度学习的流程
  8. pycharm 远程调试图文_pycharm远程调试openstack的图文教程
  9. 中小企业数智化转型,这个百万级客户市场差点被遗忘
  10. vue 调用移动录像_vue调用摄像头拍照 (移动)2020-11-18
  11. 用Javascript实现Repeater
  12. 按键精灵手机助手旋转验证码上传插件
  13. 画画不只是为了艺考,还能成为一门手艺~
  14. 普罗米修斯清除历史数据
  15. SNF快速开发平台MVC-名片管理(实际名片样式)
  16. chrome设置主页打开为百度,免去每次都要输入网址
  17. java+如何画一个扇形_实现一个扇形的几种方法
  18. Android集成百度人脸识别(一)基础版SDK
  19. 【应用实例】基于单片机的激光相位测距仪
  20. Redis管道技术的使用

热门文章

  1. NLP之WE之CBOWSkip-Gram:CBOWSkip-Gram算法概念相关论文、原理配图、关键步骤之详细攻略
  2. 自动化机器学习(三)神经网络架构搜索综述(NAS)简述
  3. OS_FLAG.C(3)
  4. web模拟telnet
  5. 移动web——基本知识点总结
  6. 【ZJ选讲·字符串折叠】
  7. Python基础之最大公约数与最小公倍数
  8. ReactiveCocoa的使用方法
  9. android开发 权限大全
  10. CentOS7关闭防火墙和SELinux