1意图

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

2别名

依赖(Dependents), 发布-订阅(Publish-Subscribe)

3动机

将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了他们的可重用性。

4实用性

1、当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将二者封装在独立的对象中以使他们可以各自独立的改变和复用。

2、当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象待改变。

3、当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。

5结构

7优缺点

1、使目标和观察者之间的耦合是抽象的最小的。

2、支持广播通信

3、意外的更新    因为一个观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。在目标上一个看视无害的操作可能会引起一系列对观察者以及依赖这些观察者的那些对象的更新。此外,如果依赖准则的定义或维护不当,常常会引起错误的更新,这种错误通常很难补捉。

--以上内容来自《可复用面向对向软件的基础》

代码实例:

本例子简单的模拟车辆运行和红绿灯的关系。例子中实现了一个Signallamp的基类(observer),凡是继承这个基类的类都可以观察红绿灯信息,并让(concreteObserver)类Vehicle,继承Signallamp。实现了一个subject的基类,凡是继承subject的concretesubject都可以被继承Signallamp的具体观察者观察,并实现子类TrafficSignal。

在客户端我们实现了几辆车在运行,当红绿灯变化时,有观察红绿灯的车将收影响。如图所以:

这里图片没有说明什么,但可以方便我们想象到客户端场景。许多车在不断的移动,当变成红灯的时候,那些观察TrafficSignal事件的车辆将停止移动,而没有观察该事件的车将不受影响。

1、observer.h中代码如下:

#ifndef _OBSERVER_
#define _OBSERVER_ #include <iostream>
using namespace std; void gotoxy(int x,int y); enum Signallamp{RedSignal, GreenSignal}; class ObserverTrafficSignal{
public:
ObserverTrafficSignal(){}
virtual void updataSignal(Signallamp signal) = ;
}; class Vehicle: public ObserverTrafficSignal{
public:
Vehicle(int px, int py):_pointx(px), _pointy(py){isRed = false;}
void drawVehicle();
void clearVehicle(); void updataposition();
void setmovestep(int stepx, int stepy); virtual void updataSignal(Signallamp signal); private:
int _pointx;
int _pointy;
int _move_x;
int _move_y;
int _save_movex;
int _save_movey;
bool isRed;
}; #endif

observer.h

2、observer.cpp中的代码如下:

#include "observer.h"

#include <iostream>
using namespace std; #include<windows.h> void gotoxy(int x,int y)
{
COORD coord={x,y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
} void conceal_cursor()
{
CONSOLE_CURSOR_INFO cci;
cci.bVisible = false;
cci.dwSize = sizeof(cci);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(handle, &cci);
} void Vehicle::drawVehicle()
{
//conceal_cursor(); int i=;
gotoxy(_pointx, _pointy+(i++));
cout<<" __________________";
gotoxy(_pointx, _pointy+(i++));
cout<<"| |";
gotoxy(_pointx, _pointy+(i++));
cout<<"|[_][_][_][_][_][_]|";
gotoxy(_pointx, _pointy+(i++));
cout<<"|o _ _ _ |";
gotoxy(_pointx, _pointy+(i++));
cout<<" `(_)-------(_)(_)-\"";
}
void Vehicle::clearVehicle()
{
int i=;
gotoxy(_pointx, _pointy+(i++));
cout<<" ";
gotoxy(_pointx, _pointy+(i++));
cout<<" ";
gotoxy(_pointx, _pointy+(i++));
cout<<" ";
gotoxy(_pointx, _pointy+(i++));
cout<<" ";
gotoxy(_pointx, _pointy+(i++));
cout<<" ";
} void Vehicle::updataposition()
{
_pointx += _move_x;
_pointy += _move_y;
if(_pointx > )
_pointx = ;
if(_pointy>)
_pointy = ;
if(_pointy<)
_pointy = ;
if(_pointx<)
_pointx = ;
}
void Vehicle::setmovestep(int stepx, int stepy)
{
_move_x = stepx; _move_y = stepy; } void Vehicle::updataSignal(Signallamp signal)
{
switch(signal)
{
case RedSignal:
if(!isRed)
{
isRed = true;
_save_movex = _move_x;
_save_movey = _move_y;
setmovestep(, );
}
break;
case GreenSignal:
if(isRed)
{
setmovestep(_save_movex, _save_movey);
isRed = false;
}
break;
}
}

observer.cpp

代码中updataSignal函数在遇见红灯时,用_save_movex和_save_movey保存了车子原始的移动速度,以便变成绿灯时恢复。

3、subject.h中的代码如下:

#ifndef _SUBJECT_
#define _SUBJECT_ #include <list>
using std::list; #include "observer.h" class subject{
public:
subject(){}
virtual void attach(ObserverTrafficSignal* ob);
virtual void detach(ObserverTrafficSignal* ob);
virtual void notify() = ; list<ObserverTrafficSignal* > _observers; }; class TrafficSignal:public subject{
public:
TrafficSignal():_countTime(),_signal(GreenSignal){}
virtual void notify(); private:
int _countTime;
Signallamp _signal;
}; #endif

subject.h

4、subject.cpp中的代码如下:

#include "subject.h"
#include<iostream>
#include <iterator>
using std::iterator; void subject::attach(ObserverTrafficSignal* ob)
{
if(NULL != ob)
_observers.push_back(ob);
} void subject::detach(ObserverTrafficSignal* ob)
{
if(NULL != ob)
_observers.remove(ob);
} void TrafficSignal::notify()
{
if(!_countTime)
{
_countTime = rand()% + ;
;
if(_signal == RedSignal)
_signal = GreenSignal;
else
_signal = RedSignal;
} _countTime--; gotoxy(, );
if(_signal == RedSignal)
std::cout<<"--红灯--";
else
std::cout<<"--绿色--"; list<ObserverTrafficSignal* >::iterator iter = _observers.begin();
for(iter; iter != _observers.end(); iter++)
{
(*iter)->updataSignal(_signal);
}
}

subject.cpp

代码中notify函数通过随即一个数_countTime的简单的模拟了红绿灯(只有红灯和绿灯),每一次运行将_countTime减一,当_countTime等于零时再次随即一个数,并更好红绿灯。

5、main.cpp中的代码如下:

#include <iostream>
using namespace std;
#include <time.h>
#include "subject.h" int main()
{
srand(time());
Vehicle ve1(, );
ve1.setmovestep(-, ); Vehicle ve2(, );
ve2.setmovestep(-, ); Vehicle ve3(, );
ve3.setmovestep(-, ); TrafficSignal tra;
tra.attach(&ve1);
//tra.attach(&ve2);
tra.attach(&ve3); while()
{
ve1.drawVehicle();
ve2.drawVehicle();
ve3.drawVehicle(); _sleep(); ve1.clearVehicle();
ve2.clearVehicle();
ve3.clearVehicle(); ve1.updataposition();
ve2.updataposition();
ve3.updataposition(); tra.notify();
}
return ;
}

观察者模式(observer)c++实现的更多相关文章

  1. 设计模式 - 观察者模式(Observer Pattern) 详细说明

    观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  2. 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)

    设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...

  3. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  4. 设计模式 - 观察者模式(Observer Pattern) 详细解释

    观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  5. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  6. 观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)

    观察者模式 Observer 意图 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新. 别名:依赖(Dependents),发布订阅(Publish-Su ...

  7. 8.5 GOF设计模式四: 观察者模式Observer

    GOF设计模式四: 观察者模式Observer  现实中遇到的问题  当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式  观察者模式 ...

  8. 设计模式-观察者模式(Observer Pattern)

    观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...

  9. jQuery中的观察者模式(Observer Pattern)

    在jQuery中,on方法可以为元素绑定事件,trigger方法可以手动触发事件,围绕这2个方法,我们来体验jQuery中的观察者模式(Observer Pattern). ■ on方法绑定内置事件, ...

  10. [Android&amp;Java]浅谈设计模式-代码篇:观察者模式Observer

    观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐.电子产品.Game.股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们.在代码中.我们也有这种一种方式来设计一些好玩的思想来.今天就写个 ...

随机推荐

  1. Ubuntu 16.04安装Atom(加强版文本工具)

    安装: sudo add-apt-repository ppa:webupd8team/atom sudo apt-get update sudo apt-get install atom 或者直接上 ...

  2. Android GIS开发系列-- 入门季(7) 利用GeometryEngine坐标转换、计算距离与面积等

    GeometryEngine是Arcgis的重要工具类,利用此工具类,可以计算地图上的距离.面积,将点.线.面转化为Json数据,将Json转化为点线面,坐标转换作用非常强大. 一.坐标转化 将用到方 ...

  3. linux下常用快捷方式

    一.终端最常用的快捷键: 1.新建终端窗口:crtl+shift+n 2.终端的切换:shift+左右箭头 3.挂起:crtl+s 4.解除挂起:crtl+q 5.清屏:crtl+l 二.命令行光标移 ...

  4. cocos2d-x+lua开发模式下编辑器的选择

    原本打算直接用CocosIDE的,毕竟是官方出品,并且支持Android远程调试,windows下的调试也非常方便,调试的信息也非常全,智能提示也不错.好了,一切看上去非常完美,可是它有一个致命缺陷, ...

  5. Android 布局自适应屏幕

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenFzNjI3NjExMzA=/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...

  6. iOS UITableViewCell 几个方法的优先级

    #第一组   - (void)setDataDict:(NSDictionary *)dataDict;这种方法优先运行 - (id)initWithStyle:(UITableViewCellSty ...

  7. OSS与文件系统的对比

    基本概念介绍_开发指南_对象存储 OSS-阿里云  https://help.aliyun.com/document_detail/31827.html 强一致性 Object 操作在 OSS 上具有 ...

  8. CANopen——总线基本知识

    1. 总线标准 2. 获取索引和子索引 2fh,2bh,23h,40h等,是不是对应cs的不同值: 主站1280h的对象字典?1280h-sub2,得到client的COB-ID值: 根据收到的m-& ...

  9. .net 接收存储过程的返回值 。。。。

    .net 接收存储过程的返回值 .... Posted on 2009-06-10 20:26 且行且思 阅读(...) 评论(...) 编辑 收藏 例如在向数据库添加新数据时,需要检测是否有重复 本 ...

  10. ASP.NET调用存储过程并接收存储过程返回值

    ASP.NET调用存储过程并接收存储过程返回值 2010-08-02 11:26:17|  分类: C#|字号 订阅       2010年02月27日 星期六 23:52 假设表结构Create T ...