观察者模式

来源:互联网 发布:java 模拟get请求 编辑:程序博客网 时间:2024/06/06 00:44

简介
观察者模式:
定义了一个一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象发生变化时,会通知所有的观察者对象,使它们可以自动更新自己。

构成
Subject(目标)
目标知道它的观察者。可以有任意多个观察者观察同一个目标;
提供注册和删除观察者对象的接口。
Observer(观察者)
为那些在目标发生改变时需获得通知的对象定义一个更新接口。
ConcreteSubject(具体目标)
将有关状态存入各ConcreteObserver对象;
当它的状态发生改变时,向它的各个观察者发出通知。
ConcreteObserver(具体观察者)
维护一个指向ConcreteSubject对象的引用;
存储有关状态,这些状态应与目标的状态保持一致;
实现Observer的更新接口以使自身状态与目标的状态保持一致。

常用的场景
在以下任一情况下都可以使用观察者模式:
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用;
2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变;
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁;也就是说,你不希望这些对象是紧密耦合的。

优点
1.观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。
由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次。
2.观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知,

缺点
1.如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2.如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。
3.如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
4.虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。

测试代码

#include <iostream>#include <assert.h>#include <vector>using namespace std;//抽象观察者class FBaseObserver{public:    virtual void update() = 0;};//观察者Aclass FObserverA : public FBaseObserver{public:    void update(){};};//观察者Bclass FObserverB : public FBaseObserver{public:    void update(){};};//抽象目标者class FBaseSubObject{public:    virtual void attached(FBaseObserver* object) = 0;    virtual void detached(FBaseObserver* object) = 0;    virtual void notify() = 0;};class FSubObjectA : public FBaseSubObject{public:    void attached(FBaseObserver* object)    {        m_lisObservers.push_back(object);    };    void detached(FBaseObserver* object)    {        for( int i = 0; i < m_lisObservers.size(); i++  )        {            if( m_lisObservers[i] == object )            {                m_lisObservers.erase(m_lisObservers.begin()+i);            }        }    };    void notify()    {        for ( int i = 0; i < m_lisObservers.size(); i++ )        {            m_lisObservers[i]->update();        }    }public:    vector<FBaseObserver*> m_lisObservers;};void main(){    FSubObjectA oSub;    FObserverA a;    FObserverB b;    oSub.attached(&a);    oSub.attached(&b);    oSub.notify();}
原创粉丝点击