设计模式 - Observer观察者模式

来源:互联网 发布:300451 创业软件股吧 编辑:程序博客网 时间:2024/06/02 06:22

1. 简单描述

观察者模式主要包括:Subject与Observers。通常observer会有多个而subject只有一个。observer将自己注册到subject中,当subject中的信息发生变化时subject便会通知该observer进行更新。subject保存所有注册的observer实例信息,在信息发生变化时通知其保存的每一个observer。这种方式是回调的一种应用。observer保存着subject的指针,subject使用array或其它同期保存observer。
subject通知observer时可以使用“推”或“拉”的方式,“推”就是subject在通知observer信息变化时直接将变化的信息作为参数传递给observer,“拉”就是subject仅仅通知observer信息有变化,而由observer自己去取得变化的信息。在多线程环境下,“推”的方式更能保证数据的准确性。

2.实例程序

subject中保存注册的observer的指针,为了使每个observer只在subject中保存一份(信息发生变化时每个observer只通知一次)使用std::set保存指针信息。

2.1 定义信息提供者

信息提供者(subject)包含observer集合成员,用来储存所有注册的观察者。attach(Observer*)用来将新的observer放入集合中。notify()接口实现当有数据变化时,遍历observer集合并通知所有注册的observer。
注意:例子中将observer的raw指针放入Observer集合,但实际使用中应该使用弱指针来避免内存泄露以及野指针问题。

//subject.h#include <set>class Observer;class Subject{public:    Subject(){}    ~Subject(){}    // regist a new observer if it does not in m_observer;    void attach(Observer* observer);    // remove one observer in m_observer;    void detach(Observer* observer);    // notify the observers to update messages;    void notify();private:    std::set<Observer*> m_observer;    typedef std::set<Observer*>::iterator ObserverIter;};


//subject.cpp
#include <iostream>#include "Subject.h"#include "Observer.h"using namespace std;void Subject::attach(Observer* observer){    if (NULL != observer)    {        pair<ObserverIter, bool> result = m_observer.insert(observer);        if (true == result.second)        {            cout<<"Subject::attach successfully registed"<<endl;        }        else        {            cout<<"Subject::attach already registed"<<endl;        }    }}void Subject::detach(Observer* observer){    if (NULL != observer)    {        int num = m_observer.erase(observer);        if (0 < num)        {            cout<<"Subject::detach successfully removed"<<endl;        }        else        {            cout<<"Subject::detach do not need remove"<<endl;        }    }}void Subject::notify(){    for (ObserverIter i = m_observer.begin(); i != m_observer.end(); ++i)    {        (*i)->update(8);    }}


2.2 定义观察者

观察者在构造时接收一个subject的指针,用来将自己注册到相应的subject中去。观察者实现了一个uodate()接口用来处理“观察到的”新数据。

// observer.hclass Subject;class Observer{public:    // regist to subject when construct    Observer(Subject* subject): m_subject(subject){}    virtual ~Observer(){}    // update message    virtual void update(int updateStr) = 0;    // remove from the old subject and regist to a new subject;    void regist(Subject* subject);    // remove from the old subject;    void remove();protected:    Subject* m_subject;};class ObserverA: public Observer{public:    ObserverA(Subject* subject);    virtual ~ObserverA(){}    virtual void update(int updateStr);};class ObserverB: public Observer{public:    ObserverB(Subject* subject);    virtual ~ObserverB(){}    virtual void update(int updateStr);};

// observer.cpp#include <iostream>#include "Observer.h"#include "Subject.h"using namespace std;void Observer::regist(Subject* subject){    if (NULL == subject)    {        cout<<"Observer::regist subject is NULL"<<endl;        return;    }    if (m_subject != subject)    {        remove();        m_subject = subject;        m_subject->attach(this);    }    else    {        cout<<"Observer::regist no need attach operation"<<endl;    }}void Observer::remove(){    if (NULL != m_subject)    {        m_subject->detach(this);        m_subject = NULL;    }}ObserverA::ObserverA(Subject* subject): Observer(subject){    if (NULL != m_subject)    {        m_subject->attach(this);    }}void ObserverA::update(int updateStr){    cout<<"ObserverA::update:   "<<updateStr<<endl;}ObserverB::ObserverB(Subject* subject): Observer(subject){    if (NULL != m_subject)    {        m_subject->attach(this);    }}void ObserverB::update(int updateStr){    cout<<"ObserverB::update:   "<<updateStr<<endl;}


2.3 测试程序

// test.cpp#include <iostream>#include "Subject.h"#include "Observer.h"using namespace std;int main(int argc, char const *argv[]){    /* code */    Subject* pSubject = new Subject();    ObserverA obA(pSubject);    ObserverB obB(pSubject);    pSubject->notify();    obB.remove();    pSubject->notify();    obB.regist(pSubject);    obB.regist(pSubject);    pSubject->notify();    return 0;}


0 0
原创粉丝点击