(一)观察者模式-C++实现
观察者模式:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。
它有四种角色:
主题(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++实现的更多相关文章
- 23种设计模式--观察者模式-Observer Pattern
一.观察者模式的介绍 观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...
- 谈谈JS的观察者模式(自定义事件)
呼呼...前不久参加了一个笔试,里面有一到JS编程题,当时看着题目就蒙圈...后来研究了一下,原来就是所谓的观察者模式.就记下来...^_^ 题目 [附加题] 请实现下面的自定义事件 Event 对象 ...
- ObserverPattern(观察者模式)
import java.util.ArrayList; import java.util.List; /** * 观察者模式 * @author TMAC-J * 牵一发而动全身来形容观察者模式在合适 ...
- java观察者模式
像activeMQ等消息队列中,我们经常会使用发布订阅模式,但是你有没有想过,客户端时如何及时得到订阅的主题的信息?其实就里就用到了观察者模式.在软件系统中,当一个对象的行为依赖于另一个对象的状态 ...
- Backbone源码解析(六):观察者模式应用
卤煮在大概一年前写过backbone的源码分析,里面讲的是对一些backbone框架的方法的讲解.这几天重新看了几遍backbone的源码,才发现之前对于它的理解不够深入,只关注了它的一些部分的细节和 ...
- PHP 高级编程(3/5) - 使用SPL(标准PHP库)实现观察者模式
SPL(标准PHP库 - Standard PHP Library)是PHP5面向对象功能中重要的部分.原文解释是这样的“The Standard PHP Library (SPL) is a col ...
- 设计模式--观察者模式初探和java Observable模式
初步认识观察者模式 观察者模式又称为发布/订阅(Publish/Subscribe)模式,因此我们可以用报纸期刊的订阅来形象的说明: 报社方负责出版报纸. 你订阅了该报社的报纸,那么只要报社发布了新报 ...
- 学C#之设计模式系列笔记(2)观察者模式
一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,观察者模式,https://zh.wikipedia.o ...
- PHP 观察者模式
观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. [观察者模式中主要角色] 1.抽象主题(Subject)角色: 抽象主题提供了增加 ...
- GJM: 设计模式 - 观察者模式
GJM : 观察者模式 视频地址: http://www.imooc.com/learn/415 本课程通过一个天气预报的发布和订阅案例,来讲解观察者模式在Java项目中的应用.主要包括观察者模式的结 ...
随机推荐
- Converse.js – 开源的 XMPP 聊天客户端
Converse.js 是一个运行在浏览器的免费和开源的聊天客户端.它可以集成到任何网页.类似于 Facebook 的聊天,它也支持多用户聊天室.Converse.js 可以连接到任何可访问的 XMP ...
- Slideout.js – 触摸滑出式 Web App 导航菜单
Slideout.js 是为您的移动 Web 应用开发的触摸滑出式的导航菜单.它没有依赖,自由搭配简单的标记,支持原生的滚动,您可以轻松地定制它.它支持不同的 CSS3 转换和过渡.最重要的是,它只是 ...
- JS Nice – JavaScript 代码美化和格式化工具
JS Nice 是一款让经过混淆处理的 JavaScript 代码可读更好的工具.它使用一种新型的用于 JavaScript 代码美化的去混淆和去压缩引擎.JSNice 采用先进的机器学习和程序分析技 ...
- filezilla sftp 文件和linux 文件不同步的问题
删除掉以前的链接,重新建立链接就好了
- NSFileManager和NSFileHandler的作用
NSFileManager类可以管理文件系统中的文件和目录,也可以定位.判断是否存在.创建.拷贝.删除文件和目录,还可以获得文件和目录的信息: 对于读写文件,NSFileManager只可以读写字符串 ...
- spring.net (1) 概念-控制反转(又名依赖注入)
Spring.net 作为一个应用程序框架,在构建企业级.net应用程序提供了很多灵活而又丰富的功能(如:依赖注入,aop,数据访问抽象,asp.net 扩展). 控制反转: Inversion of ...
- Android Studio no debuggable applications解决方案
android studio 默认是没有开启debuggable 功能的,在tools里打开该功能即可,Tools->Android->Enable ADB Integration. 刚设 ...
- Android自定义控件1--自定义控件介绍
Android控件基本介绍 Android本身提供了很多控件比如我们常用的有文本控件TextView和EditText:按钮控件Button和ImageButton状态开关按钮ToggleButton ...
- IOS 四舍五入 进一法 去尾法
float numberToRound; int result; numberToRound = 4.51; result = (int)roundf(numberToRound); NSLog(@& ...
- RDVTabBarController的基本使用 以及tabbar的防止双点击方法
RDVTabBarController这个库写得相当不错,所以今天就简单介绍下它的基本使用,看里面可以清楚的知道代码规范的重要性,这个库的使用方法和官方的相识 下载地址:https://github. ...