观察者模式(observer)c++实现
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++实现的更多相关文章
- 设计模式 - 观察者模式(Observer Pattern) 详细说明
观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)
设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...
- 设计模式 - 观察者模式(Observer Pattern) 详细解释
观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- java设计模式--观察者模式(Observer)
java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...
- 观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)
观察者模式 Observer 意图 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新. 别名:依赖(Dependents),发布订阅(Publish-Su ...
- 8.5 GOF设计模式四: 观察者模式Observer
GOF设计模式四: 观察者模式Observer 现实中遇到的问题 当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式 观察者模式 ...
- 设计模式-观察者模式(Observer Pattern)
观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...
- jQuery中的观察者模式(Observer Pattern)
在jQuery中,on方法可以为元素绑定事件,trigger方法可以手动触发事件,围绕这2个方法,我们来体验jQuery中的观察者模式(Observer Pattern). ■ on方法绑定内置事件, ...
- [Android&Java]浅谈设计模式-代码篇:观察者模式Observer
观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐.电子产品.Game.股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们.在代码中.我们也有这种一种方式来设计一些好玩的思想来.今天就写个 ...
随机推荐
- Ubuntu 16.04安装TeamViewer
安装i386库: sudo apt-get install libc6:i386 libgcc1:i386 libasound2:i386 libexpat1:i386 libfontconfig1: ...
- Java的文件注释
以下内容引用自http://wiki.jikexueyuan.com/project/java/documentation.html: Java语言支持三种注释形式: 注释 描述 /*text*/ 编 ...
- CentOS系统下Hadoop、Hbase、Zookeeper安装配置
近期给一个项目搭建linux下的大数据处理环境,系统是CentOS 6.3.主要是配置JDK.安装Tomcat,Hadoop.HBase和Zookeeper软件.博主在Hadoop这方面也是新手.配置 ...
- Vue中删除重复上传的文件
上传控件: <el-upload class="upload-demo" :on-change="filesChange"> filesChang ...
- HDU 4950 Monster(公式)
HDU 4950 Monster 题目链接 题意:给定怪兽血量h,你攻击力a.怪物回血力b,你攻击k次要歇息一次,问是否能杀死怪兽 思路:签到题,注意最后一下假设打死了怪,那么怪就不会回血了 思路: ...
- HDU 1226 超级password
跟POJ 1465 multiple 类是.仅仅只是多了2个条件,长度不能超过500.还有就是 可能不是十进制. bfs+同余定理,就是用 mod 来判重. G++ 15ms 每次枚举一位,然后记录下 ...
- libXdmcp.so.6
Traceback (most recent call last): File "/data/xiaole_dl_img/product.v.one.banner.fixedperiod.g ...
- LightTable的结构(二)
这节主要研究下object的一个属性,behaviors 定义一个behavior需要提供name,trigger,reaction (behavior ::on-close-destroy :tri ...
- 【转载pku】三十分钟掌握STL
三十分钟掌握STL 这是本小人书.原名是<using stl>,不知道是谁写的.不过我倒觉得很有趣,所以化了两个晚上把它翻译出来.我没有对翻译出来的内容校验过.如果你没法在三十分钟内觉得有 ...
- android获取手机的IMSI码
android--获取手机的IMSI码,并判断是中国移动\中国联通\中国电信转载 TelephonyManager telManager = (TelephonyManager) getSystemS ...