观察者模式:

定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。

它有四种角色:

主题(Subject):一个接口,规定了具体主题需要实现的方法。

观察者(Observer):也是一个接口,规定了具体观察者用来更新数据的方法。

具体主题:实现主题接口的一个实例,比如本例中的“就业通知中心”;里面会维护一个具体观察者的集合。本文使用STL中的list。

具体观察者:实现观察者的一个实例,会包含存放主题的引用或者指针。

使用C++实现如下:

包含5个文件,头文件两个:主题类(Subject.h)观察者类(Observer.h)

源文件两个:主题类(Subject.cpp)观察者类(Observer.h)

一个测试文件。

//Subject.h

#ifndef _SUBJECT_H_
#define _SUBJECT_H_
#include "Observer.h"
#include <list>
#include <string>
using namespace std;
class Observer;//注意C++中虽然包含了头文件这里也需要声明
typedef list<Observer*> myList; class Subject{
public:
Subject(){}
virtual ~Subject(){}
virtual void addObserver(Observer* o) = 0;
virtual void deleteObserver(Observer* o) = 0;
virtual void notifyObservers() = 0; }; class SeekJobCenter : public Subject
{
public:
SeekJobCenter();
~SeekJobCenter(){}
void addObserver(Observer* o);
void deleteObserver(Observer* o); void notifyObservers();
void giveNewMessage(string str); private:
string mess;
bool changed;
myList personList; }; #endif

//Subject.cpp

//具体的主题
#include "stdafx.h"
#include "Subject.h"
#include "Observer.h"
#include <list> SeekJobCenter::SeekJobCenter()
{
mess = "";
changed = false;
}
void SeekJobCenter::addObserver(Observer* o)
{
list<Observer*>::iterator it;
//判断原始维护的list中是否存在添加的对象
it = find(personList.begin(), personList.end(), o);
if (it == personList.end())//不存在
{
personList.push_back(o);
}
return;
} void SeekJobCenter::deleteObserver(Observer* o)
{
list<Observer*>::iterator it;
it = find(personList.begin(), personList.end(), o);
if (it != personList.end())//存在
{
personList.remove(*it);
delete(*it);
}
return;
} void SeekJobCenter::notifyObservers()
{
list<Observer*>::iterator it;
if (changed)
{
for (it = personList.begin(); it != personList.end(); ++it)
{
(*it)->hearTelephone(mess);
}
changed = false;
}
return;
} void SeekJobCenter::giveNewMessage(string str)
{
if (0 == strcmp(str.c_str(), mess.c_str()))
{
changed = false;
}
else
{
mess = str;
changed = true;
}
return;
}

//Observer.h

#ifndef _OBSERVER_H_
#define _OBSERVER_H_
#include <string>
#include <iostream>
#include <list>
#include "Subject.h"
using namespace std;
class Subject;
/*
观察者基类
*/
class Observer
{
public:
Observer(){};
virtual ~Observer(){};
virtual void hearTelephone(string heardMess) = 0; }; class UniversityStudent : public Observer
{
public:
UniversityStudent(Subject* subject);
virtual ~UniversityStudent(){};
void hearTelephone(string heardMess); private:
Subject* subject; }; class HaiGui : public Observer
{
public:
HaiGui(Subject *subject);
virtual ~HaiGui(){};
void hearTelephone(string heardMess); private:
Subject *subject; }; #endif

//Observer.cpp

 #include "stdafx.h"
#include "Observer.h"
#include "Subject.h" UniversityStudent::UniversityStudent(Subject* subject)
{
if (NULL != subject)
{
this->subject = subject;
}
else
{
return;
} subject->addObserver(this);
}
void UniversityStudent::hearTelephone(string heardMess)
{
std::cout << "I am a university student" << std::endl;
std::cout << "I hear message is " << heardMess << std::endl;
return;
} HaiGui::HaiGui(Subject* subject)
{
if (NULL != subject)
{
this->subject = subject;
}
else
{
return;
}
subject->addObserver(this);
} void HaiGui::hearTelephone(string heardMess)
{
std::cout << "I am a HaiGui" << std::endl;
std::cout << "I hear message is " ;
cout << heardMess << endl;
return;
}

最后一个测试的文件:

#include "stdafx.h"
#include "Observer.h"
#include "Subject.h" int _tmain(int argc, _TCHAR* argv[])
{
SeekJobCenter *center = new SeekJobCenter();
UniversityStudent *chengchaolee = new UniversityStudent(center);
HaiGui *haigui = new HaiGui(center);
center->giveNewMessage("I need a cook");
center->notifyObservers();
center->giveNewMessage("I need a xxxx");
center->notifyObservers(); delete center;
delete chengchaolee;
delete haigui;
return 0;
}

定义两个具体的观察者,并且以具体主题作为参数,代表它观察的对象,然后当主题推送数据时,观察者就会收到消息,即“推数据”的方式,当然还有一种观察者模式采用的是拉数据,即由观察者自己定义需要什么数据,主题在notify的时候并不传递参数而是在观察者更新数据时,将Subject向下转换为具体Subject,从而获取其中相应的数据,这种方式叫做“拉数据”。

值得注意的是,C++在实现的时候,采用list存储具体观察者,需要使用list<Observer*>类型,即使用指针。不然会编译不通过,因为Observer是虚基类,无法实例化。

(一)观察者模式-C++实现的更多相关文章

  1. 23种设计模式--观察者模式-Observer Pattern

    一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...

  2. 谈谈JS的观察者模式(自定义事件)

    呼呼...前不久参加了一个笔试,里面有一到JS编程题,当时看着题目就蒙圈...后来研究了一下,原来就是所谓的观察者模式.就记下来...^_^ 题目 [附加题] 请实现下面的自定义事件 Event 对象 ...

  3. ObserverPattern(观察者模式)

    import java.util.ArrayList; import java.util.List; /** * 观察者模式 * @author TMAC-J * 牵一发而动全身来形容观察者模式在合适 ...

  4. java观察者模式

      像activeMQ等消息队列中,我们经常会使用发布订阅模式,但是你有没有想过,客户端时如何及时得到订阅的主题的信息?其实就里就用到了观察者模式.在软件系统中,当一个对象的行为依赖于另一个对象的状态 ...

  5. Backbone源码解析(六):观察者模式应用

    卤煮在大概一年前写过backbone的源码分析,里面讲的是对一些backbone框架的方法的讲解.这几天重新看了几遍backbone的源码,才发现之前对于它的理解不够深入,只关注了它的一些部分的细节和 ...

  6. PHP 高级编程(3/5) - 使用SPL(标准PHP库)实现观察者模式

    SPL(标准PHP库 - Standard PHP Library)是PHP5面向对象功能中重要的部分.原文解释是这样的“The Standard PHP Library (SPL) is a col ...

  7. 设计模式--观察者模式初探和java Observable模式

    初步认识观察者模式 观察者模式又称为发布/订阅(Publish/Subscribe)模式,因此我们可以用报纸期刊的订阅来形象的说明: 报社方负责出版报纸. 你订阅了该报社的报纸,那么只要报社发布了新报 ...

  8. 学C#之设计模式系列笔记(2)观察者模式

    一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,观察者模式,https://zh.wikipedia.o ...

  9. PHP 观察者模式

    观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. [观察者模式中主要角色] 1.抽象主题(Subject)角色: 抽象主题提供了增加 ...

  10. GJM: 设计模式 - 观察者模式

    GJM : 观察者模式 视频地址: http://www.imooc.com/learn/415 本课程通过一个天气预报的发布和订阅案例,来讲解观察者模式在Java项目中的应用.主要包括观察者模式的结 ...

随机推荐

  1. 高性能javascript学习笔记系列(4) -算法和流程控制

    参考高性能javascript for in 循环  使用它可以遍历对象的属性名,但是每次的操作都会搜索实例或者原型的属性 导致使用for in 进行遍历会产生更多的开销 书中提到不要使用for in ...

  2. 百度在线编辑器UEditor(v1.3.6) .net环境下详细配置教程之更改图片和附件上传路径

    本文是接上一篇博客,如果有疑问请先阅读上一篇:百度在线编辑器UEditor(v1.3.6) .net环境下详细配置教程 默认UEditor上传图片的路径是,编辑器包目录里面的net目录下 下面就演示如 ...

  3. atitit.身份认证解决方案attilax总结

    atitit.身份认证解决方案attilax总结 1.1. 身份认证1 1.2.  basic认证1 1.2.1. 编程实现basic客户端2 1.3. digest认证机制3 1.4. SSL认证3 ...

  4. 为Windows Azure Web站点添加MIME类型解决文件下载失败的问题

    这几天在倒腾Autodesk 360 Viewer,前面的文章也介绍过了,这将是一个全新的在线模型浏览工具.我做了个实验,把A360Viewer放在一个web 站点,然后发布到Windows Azur ...

  5. [Android]使用Kotlin开发Android(二)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4829007.html [TOC] 使用Kotlin+OkHtt ...

  6. Android项目开发实战-2048游戏

    <2048>是一款比较流行的数字游戏,最早于2014年3月20日发行.原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台.这款游戏是基于&l ...

  7. mac os intellij如何快路查看一个java类的所有方法,结构

    如果是自己写的java类,点击点击导航的project-setting-show members 如果是系统库的,点击structure 再点一下lib中的类,或者快捷键 command+F12

  8. UIPickerView简单应用

    下面是一些效果图 下面是代码.有些枯燥 , 其实并不难 . #import <UIKit/UIKit.h> @interface ViewController : UIViewContro ...

  9. GIT在iOS开发中的使用

    前言 在iOS开发中,很多公司对项目的版本控制管理都使用了git,当然也有部分公司使用的是svn.当年我最初接触的是svn,觉得使用起来挺方便的,但是每次切分支都需要下载一份新的代码起来,这实在太麻烦 ...

  10. CRM项目经验总结-从DAO层到链接数据池

    IDAO接口 定义项目中所有板块相似功能 也是整个项目的根接口  public interface IDAO {  /**   * 新增数据 @param SQL sql查询语句  @param pa ...