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. Cisco网络设备命名规则

      1. CISCO 开头的产品都是路由器:2. RSP 开头的都是CISCO7500 系列产品的引擎:3. VIP 开头的产品都是CISCO 7500系列产品的多功能接口处理器模块:4. PA 开头 ...

  2. 我的arcgis培训照片8

    来自:http://www.cioiot.com/successview-554-1.html

  3. 012 router password

    Press RETURN to get started!       Router>en Router#config t Enter configuration commands, one pe ...

  4. openTSDB ConnectionManager: Unexpected exception from downstream java.io.IOException: Broken pipe

    openTSDB有这种错误: ConnectionManager: Unexpected exception from downstream for [id: 0xf85323a8, /10.65.3 ...

  5. 怎样用fiddler2捕获移动设备上的http或者https请求

    调试移动设备上的问题.看不到发送的请求和得到的响应是比較难过的,fiddler能够实现样的功能. 原理: 在PC上启动fiddler.将手持设备的网络代理改成fiddler. 这样全部的请求和响应都经 ...

  6. hdu 1565 方格取数(1)(状态压缩dp)

    方格取数(1)                                                                 Time Limit: 10000/5000 MS (J ...

  7. Java语言中extend和implement的区别

    Java语言并不支持多重继承,而只能继承一个类,不过我们可以使用implements来实现多个接口. extends继承的父类:不能声明为final或者定义为abstract: implements实 ...

  8. Paypal支付(一)MPL真正的快捷支付

    一.前导 前面讲到了MEC支付,是在Web端集成好的,在手机端仅仅需通过WebView进行载入就可以,不须要不论什么Paypal第三方架包.以下将的是MPL支付.须要架包. 这样的支付的形式能够參考以 ...

  9. 【bzoj4590】[Shoi2015]自动刷题机

    因为解一定是单调的,n越小切的题越多,这是可以肯定的,那么直接二分答案 #include<algorithm> #include<iostream> #include<c ...

  10. APDU报文【转】

    本文转载自:http://www.cnbolgs.com/snail0404/p/5436348.html APDU   # APDU # 定义:APDU(ApplicationProtocolDat ...