观察者(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
原创粉丝点击