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. mysql性能调优——Query优化

    上节谈了关于mysql锁定机制的优化方案,下面来谈一下Query优化——Mysql Query Optimizer 当Mysql Query Optimizer接受到从Query Parser过来的Q ...

  2. http转https

    1.先用jdk生成证书 先跳转到jdk的bin目录下:E:\Program Files\Java\jdk1.8.0_91\bin>keytool -genkey -alias tomcat -k ...

  3. omnidazzle是mac的画笔工具

    先使用命令 brew cask install omnidazzle 试试,不行参考下面: http://macappstore.org/omnidazzle/

  4. 条款十五: 让operator=返回*this的引用

    c++程序员经常犯的一个错误是让operator=返回void,这好象没什么不合理的,但它妨碍了连续(链式)赋值操作,所以不要这样做. 一般情况下几乎总要遵循operator=输入和返回的都是类对象的 ...

  5. windows 7 文件加密设置

    方法/步骤1 加密文件 1 右击需加密的文件,选择“属性”命令. 2 在属性对话框的“常规‘选项卡中单击”高级“按钮. 3 在弹出的对话框中选中”加密内容以便保护数据“复选框,单击”确定“按钮. 4 ...

  6. 关于使用data()获取自定义属性出现undefined的说明

    这应该是这个函数的一个bug,没有考虑到驼峰式的写法,当我写成驼峰式,即是有大小写的变量时就会出现没有定义的情况. 今天写个交互,需要用到自定义属性,因为这个自定义属性是当作字段用的,就直接用了字段名 ...

  7. cmd启动Oracle服务和监听服务

    启动数据库服务 net start oracleserviceorcl 启动数据库监听 lsnrctl start

  8. 【bzoj2728】[HNOI2012]与非

    先打出nand表 0 nand 0=1 1 nand 1=0 0 nand 1=1 1 nand 0=1   容易发现(!a)=a nand a 然后(a&b)=!(a nand b) 然后( ...

  9. doGet() throws NamingException报错

    做一个通过JNDI查找资源的小练习,Context = new InitialContext(),发现NamingException异常,eclipse编辑器只有catch的提示,没有throws的提 ...

  10. TableLayout与MigLayout

    最近新接触的两个Layout,另外之前用的GridBagLayoutHelper以及最近听说的Qt for java的QCSS据说也不错, 只是Qt的跨平台需要单独发布,假如使用QT for java ...