一、什么是观察者模式

Observer模式也叫观察者模式,是由GoF提出的23种软件设计模式的一种。Observer模式是行为模式之中的一个,它的作用是当一个对象的状态发生变化时,可以自己主动通知其它关联对象,自己主动刷新对象状态。

  观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个样例,用户界面能够作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每一个类将重点放在某一个功能上,而不是其它方面。一个对象仅仅做一件事情,而且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

  观察者模式有非常多实现方式,从根本上说,该模式必须包括两个角色:观察者和被观察对象。在刚才的样例中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这种变化,而且做出对应的响应。假设在用户界面、业务数据之间使用这种观察过程,能够确保界面和数据之间划清界限,假定应用程序的需求发生变化,须要改动界面的表现,仅仅须要又一次构建一个用户界面,业务数据不须要发生变化。

  “观察”不是“直接调用”

  实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。不管是观察者“观察”观察对象,还是被观察者将自己的改变“通知”观察者,都不应该直接调用。

  实现观察者模式的形式

  实现观察者模式有非常多形式,比較直观的一种是使用一种“注冊——通知——撤销注冊”的形式。

实现观察者模式样例

以下是C++的实现,在C++实现中,C++中没有接口的概念,可是能够用抽象类类取代Java或C#中的接口,在C++中抽象类中从派生类中抽象出来的函数(方法),必须定义成纯虚函数,这样在后面的使用中才干够通过基类的指针来訪问这些函数,面向对象的语言中有个特点,多态仅仅能訪问两者中共同拥有的部分。

//实例源自http://blog.csdn.net/ocean181/archive/2010/09/11/5877621.aspx#1607956 ,主要做了点修正.

#include <iostream>
#include <list>
#include <string>
using namespace std;

class Observer;
class Subject
{
public:
 virtual void attach(Observer *o)=0;
 virtual void change()=0;
 virtual void setWeather(string str)=0;
 virtual string getWeather()=0;
};
class Observer
{
public:
 virtual string getName()=0;
 virtual void update(Subject *s)=0;
};

class Earth: public Subject
{
private:
 string weather;
 list<Observer* >* l;//指针
public:
 Earth()
 {
  l = new list<Observer*>;
 }
 void attach(Observer *o)
 {
  this->l->push_back(o);
 };
 void change()
 {
  for(list<Observer*>::iterator it=l->begin();it!=l->end();++it)
  {
   (*it)->update(this);
  }
 };
 void setWeather(string str)
 {
  this->weather=str;
  change();
 };
 string getWeather()
 {
  return this->weather;
 };
};
class Satellite:public Observer
{
private:
 string name;
public:
 Satellite(string str)
 {
  name=str;
 }
 string getName()
 {
  return name;
 };
 void update(Subject *s)
 {
  cout<<this->getName()+" "+s->getWeather();
 }
};

int main()
{
 Earth e;
 Satellite *s1 = new Satellite("风云一号");
 Satellite *s2 = new Satellite("风云二号");
 Satellite *s3 = new Satellite("风云三号");
 Satellite *s4 = new Satellite("风云四号");
 e.attach(s1);
 e.attach(s2);
 e.attach(s3);
 e.attach(s4);
 e.setWeather("fine");

while(1){}
 return 0;
}

观察者模式的程序实例C++的更多相关文章

  1. (转)实战Memcached缓存系统(5)Memcached的CAS程序实例

    1. 非CAS 首先看一个不是CAS的Memcached程序实例.实例的问题原型,见上一篇博文. 程序实例: package com.sinosuperman.memcached; import ja ...

  2. 如何让Windows程序只运行一个程序实例?

    要实现VC++或者MFC只运行一个程序实例,一般采用互斥量来实现,即首先用互斥量封装一个只运行一个程序实例的函数接口: HANDLE hMutex = NULL; void MainDlg::RunS ...

  3. Linux Epoll介绍和程序实例

    Linux Epoll介绍和程序实例 1. Epoll是何方神圣? Epoll但是当前在Linux下开发大规模并发网络程序的热门人选,Epoll 在Linux2.6内核中正式引入,和select类似, ...

  4. 微信小程序实例源码大全

    微信小程序实例源码大全下载 微信小应用示例代码(phodal/weapp-quick)源码链接:https://github.com/phodal/weapp-quick 微信小应用地图定位demo( ...

  5. MFC 只启动一个程序实例

    问题描述: 我们开发过程中可能会经常遇到,只启动一个程序实例.即一个程序启动之后,如果再次执行该程序,将会恢复之前打开的程序,而不是打开一个新的程序. 实现原理:利用FindWindow/FindWi ...

  6. 一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(四) --高级设置二

    原文:一个完整的Installshield安装程序实例-艾泽拉斯之海洋女神出品(四) --高级设置二 上一篇:一个完整的安装程序实例—艾泽拉斯之海洋女神出品(三) --高级设置一4. 根据用户选择的组 ...

  7. 微信小程序实例教程(一)

    序言 开始开发应用号之前,先看看官方公布的「小程序」教程吧!(以下内容来自微信官方公布的「小程序」开发指南) 本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果.这个小程序 ...

  8. JDBC 程序实例小练习

    JDBC 程序实例问题 编程实现如下功能:在数据库中建立一个表,表名为student,其结构为学号.姓名.性别.年龄.英语.JavaSE程序设计.初级日语.总分,在表中输入多条记录. 学生的总分信息, ...

  9. C++程序实例唯一方案,窗口只打开一次,程序只打开一次

    首先是方法: // IsAlreadyRunning - 是否已经运行 BOOL IsAlreadyRunning() { BOOL bRet = FALSE; HANDLE hMutex = ::C ...

随机推荐

  1. 【剑指offer学习】求和为定值的两个数(拓展)

    接着上面一篇文章: http://blog.csdn.net/u013476464/article/details/40651451 接下来我们拓展一下题目,如果数组是乱序的,并且规定数组中的元素所有 ...

  2. [Aaronyang] 写给自己的WPF4.5 笔记15[AyArc诞生-WPF版本绚丽的环状图,Ay制作,AyWindow强势预览]

    原文:[Aaronyang] 写给自己的WPF4.5 笔记15[AyArc诞生-WPF版本绚丽的环状图,Ay制作,AyWindow强势预览]  我的文章一定要做到对读者负责,否则就是失败的文章  -- ...

  3. 数据库 版本号是 661,打不开。此server支持 655 和更早的版本号。不支持降级路径

    "数据库 的版本号为 661,无法打开.此server支持 655 版及更低版本号. 不支持降级路径" 出现这种问题,通常是由于数据库版本号不同造成的. 我们能够用以下的语句查询数 ...

  4. cocos2d-x box2d Demo注解

    勤奋努力,持之以恒. 核心概念 Box2D 中有一些主要的对象,这里我们先做一个简要的定义,在随后的文档里会有更具体的描写叙述. 刚体(rigid body) 一块十分坚硬的物质,它上面的不论什么两点 ...

  5. cocos2d-x—使用shader使图片背景透明

    这里用shader处理了像素,使黑色背景透明,直接上代码 ShaderSprite.h [cpp] view plaincopyprint? #ifndef __TestShader__ShaderS ...

  6. WEB功能测试说明

    站点功能測试就是对产品的各功能进行验证.依据功能測试用例,逐项測试.检查产品是否达到用户 要求的功能.经常使用的測试方法例如以下: 1.页面链接检查: 每个链接是否都有相应的页面.而且页面之间切换工具 ...

  7. HDU 3832 Earth Hour(最短路)

    题目地址:HDU 3832 这个题的这种方法我无法给出证明. 我当时这个灵感出来的时候是想的是要想覆盖的点最少,那就要尽量反复利用这些点,然后要有两个之间是通过还有一个点间接连接的,这样会充分利用那些 ...

  8. 修改Hosts不生效的一个场景-web(转)

    Update: 如果浏览器使用了代理工具,修改 Hosts 也不会生效.这里是因为,浏览器会优先考虑代理工具(如添加 pac 文件.SwitchySharp等)的代理,建议调试的时候先关闭这些代理. ...

  9. Android开发人员官方站点文档 - 国内踏得网镜像

    Android Developer 安卓开发人员官方站点无法正常訪问.即使FQ因为网络原因依旧訪问缓慢. 故整理相关字体.脚本.样式.页面资源,在踏得网server上建立了本地镜像.初始镜像时间201 ...

  10. 数据存储(两)--SAX发动机XML记忆(附Demo)

    Android SDK支撑SAX读取技术XML,SAX通过连续的读取方式来处理XML文件.这要求每个读数XML对应的事件触发,以处理该节点的文件的节点.以下是基于一个例子来告诉SAX使用: publi ...