观察者(Observer)
来源:互联网 发布:apache johnzon 编辑:程序博客网 时间:2024/06/01 10:17
观察者(observer)是一种对象行为型模式。
1.目的
定义对象间的一种一对多的依赖关系,当一个对象当状态发生改变时,所有依赖于它的对象都可以得到通知并被自动更新。一个例子就是所有联网的电脑都可以拥有一致的互联网时间,这里网络时间其实就可以看作一个目标,而每台联网的主机都可以看作一个观察者。每台主机得到通知并更新自己都时间显示。
2.适用性
(1)一个抽象模型有两个方面,其中一个依赖于另一个方面。利用观察者模式可以独立封装这两个抽象模型,使得他们可以各自独立地改变和复用。
(2)当对一个对象的改变需要同时改变其他对象时,而又不知道具体有多少对象有待改变。其实这里也蕴含着动态地绑定和解绑定观察者。
(3)当一个对象必须通知其他对象,而又不能假定其他对象到底是什么。这里继承就派上了用场,从而实现对象的紧密解耦。
3.优缺点
(1)目标和观察者之间的抽象解耦:可以分开设计,而只需要最小的接口。
(2)支持广播通信:可以只存在一个目标,而存在多个观察者,只要这些观察者对目标进行绑定或者称注册,则目标就可以向其广播并更新。
(3)缺点在于可能导致意外对更新。因为观察者之间并非相互知道,因此一个观察者对更新可能影响另一个观察者。另外一个缺点在于更新对代价可能很大,频繁更新时则得不偿失,解决的方案可以是采用一个更改管理器,它将维护整个映射并定义特定的更新策略(如足够多的更新存在时才去更新)。
4.代码示例
头文件定义:
//// Observer.h// Observer//// Created by CHM on 14-7-7.// Copyright (c) 2014年 CHM. All rights reserved.// 假定两个间谍相互配合去完成一项任务,任务内容必须在30s内同时完成。// 这时需要给他们一个同样的时间提示。如果他们都有一个时间显示器timer(就是observer),// 因此需要一个Clock(就是subjet)来为他们同步时间。#ifndef Observer_Observer_h#define Observer_Observer_h#include <iostream>#include <list>#include <boost/timer.hpp>using namespace std;using namespace boost;/**********************subject***************************/class Clock;/************************observer************************/class Timer{public: virtual void Update(Clock*)=0; virtual void Display()=0; virtual ~Timer(){}};//间谍aclass SpyA:public Timer{public: SpyA(Clock* clock):_clock_a(clock),_remand_time_a(0){} virtual void Update(Clock*); virtual void Display();private: Clock* _clock_a; int _remand_time_a;};//间谍bclass SpyB:public Timer{public: SpyB(Clock* clock):_clock_b(clock),_remand_time_b(0){} virtual void Update(Clock*); virtual void Display();private: Clock* _clock_b; int _remand_time_b;};/********************************************************/class Clock{public: Clock* Instance() { static Clock* _clock_p=new Clock(30); return _clock_p; } //绑定和解绑定操作 void Attach(Timer*); void Detach(Timer*); //得到现在的时间 int Get_Time() const { return _time; } //通知更新 void Notify(); //为了计时,实现每秒更新一次 void Mission_Start();private: Clock(int time):_time(time){} Clock(const Clock&); Clock& operator=(const Clock&);private: list<Timer*> _list; int _time; };#endif
实现文件(这里没有采用inline)://// Observer.cpp// Observer//// Created by CHM on 14-7-7.// Copyright (c) 2014年 CHM. All rights reserved.//#include <stdio.h>#include "Observer.h"/**************************************************/void Clock::Attach(Timer* timer){ _list.push_back(timer);}void Clock::Detach(Timer* timer){ _list.remove(timer);}void Clock::Notify(){ list<Timer*>::iterator ix=_list.begin(); while(ix!=_list.end()) { (*ix)->Update(this); ++ix; }}void Clock::Mission_Start(){ //通知开始时间,任务开始 Notify(); //利用定时,每1秒通知一次,更新间谍a和b的时间状态 timer t; int last_time=t.elapsed(); while(_time>0) { while(t.elapsed()-last_time<1); _time-=1; Notify(); last_time=t.elapsed(); }}/******************************************************/void SpyA::Update(Clock* clock){ _remand_time_a=clock->Get_Time(); //这里的输出仅仅为了方便查看结果 Display();}void SpyA::Display(){ cout<<"SpyA remand time is: "<<_remand_time_a<<endl;}/******************************************************/void SpyB::Update(Clock* clock){ _remand_time_b=clock->Get_Time(); Display();}void SpyB::Display(){ cout<<"SpyB remand time is: "<<_remand_time_b<<endl;}
5.测试代码//目标部分,不完整的单例模式 Clock* pt; Clock* p=pt->Instance(); //为了得到信息,所以给定目标 SpyA* pa=new SpyA(p); SpyB* pb=new SpyB(p); //绑定观察者 p->Attach(pa); p->Attach(pb); //任务开始 p->Mission_Start();
0 0
- 观察者模式(OBSERVER)
- 观察者(Observer)模式
- 观察者(Observer)模式
- Observer(观察者)
- 观察者(Observer)模式
- 观察者(Observer)模式
- 观察者模式(Observer)
- 观察者模式(Observer)
- Observer(观察者)模式
- 观察者模式(Observer)
- Observer(观察者模式)
- 观察者模式(Observer)
- 观察者模式(Observer)
- 观察者模式(Observer)
- 观察者模式(Observer)
- 观察者模式(Observer)
- 观察者(Observer)模式
- 观察者模式(Observer)
- Foundation中的NSMutableString的创建
- javaee中的编码问题
- 关于BCB的安装过程
- cocos2d-x在Eclipse上重新编译成Android可执行的文件
- android常见的一些工具类的方法
- 观察者(Observer)
- csv转成Excel
- CentOS6.5编译部署64位Hadoop2.2.0
- ActionBar
- 在COM组件中调用JavaScript函数
- Android开发记录三之单选、多选按钮及进度条
- 提高你的Python: 解释‘yield’和‘Generators(生成器)’
- hdu 4029 Distinct Sub-matrix ( 后缀数组 + Hash )
- 怎样不使用迅雷而使用浏览器自带的下载进行下载