Design Pattern之观察者模式

观察者模式又叫发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
下面是观察者模式的结构图:
这里写图片描述
Subject类把所有对观察者对象的引用保存在一个聚集里,,每个主题都可以有任何数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。Observer类抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。ConcreteSubject类具体主题,将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知;ConcreteObserver类,具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。
以下是代码例子:

#ifndef __SUBJECT__H__
#define __SUBJECT__H__
#include <string>

using namespace std;

class Observer;

class Subject
{
public:
    virtual ~Subject(){}
    virtual void Attach(Observer* __o) = 0;
    virtual void Detach(Observer* __o) = 0;
    virtual void Notify( ) = 0;
    virtual string& GetSubjectAction() = 0;
    virtual void   SetSubjectAction(const string& __s ) = 0;
};
#ifndef __OBSERVER__H__
#define __OBSERVER__H__

#include <string>
using namespace std;

class Subject;

class Observer
{
public:
    Observer(string __name, Subject* __sub)
    {
        m_strName = __name;
        m_pSub = __sub;
    }
    virtual ~Observer() 
    {

    }

    virtual void Update() = 0;
protected:
    string m_strName; 
    Subject* m_pSub;
};
#endif // !__OBSERVER__H__
#ifndef __BOSS__H__
#define __BOSS__H__

#include "Observer.h"
#include "Subject.h"
#include <list>
class Boss : public Subject
{
private:
    list<Observer*> m_lObervers;
    string m_strAction;
public:
    virtual void Attach(Observer* __o)
    {
        m_lObervers.push_back(__o);
    }
    virtual void Detach(Observer* __o)
    {
        m_lObervers.remove(__o);
    }
    virtual void Notify()
    {
        for (list<Observer*>::iterator it = m_lObervers.begin(); it != m_lObervers.end(); it++)
        {
            Observer* __o = *it;
            __o->Update();
        }
    }
    virtual string& GetSubjectAction()
    {
        return m_strAction;
    }
    virtual void   SetSubjectAction(const string& __s)
    {
        m_strAction = __s;
    }

};
#endif // !__BOSS
#ifndef __SECRETARY__H__
#define __SECRETARY__H__

#include "Observer.h"
#include "Subject.h"
#include <list>
class Secretary : public Subject
{
private:
    list<Observer*> m_lObervers;
    string m_strAction;
public:
    virtual void Attach(Observer* __o)
    {
        m_lObervers.push_back(__o);
    }
    virtual void Detach(Observer* __o) 
    {
        m_lObervers.remove(__o);
    }
    virtual void Notify()
    {
        for (list<Observer*>::iterator it = m_lObervers.begin(); it != m_lObervers.end(); it++)
        {
            Observer* __o = *it;
            __o->Update();
        }
    }
    virtual string& GetSubjectAction()
    {
        return m_strAction;
    }
    virtual void   SetSubjectAction( const string& __s )
    {
        m_strAction = __s;
    }

};
#endif // !__SECRETARY
#ifndef __NBAOBSERVER__H__
#define __NBAOBSERVER__H__
#include "Observer.h"
#include "Subject.h"
#include <stdio.h>


class NBAObserver : public Observer
{
public:
    NBAObserver(string __n, Subject* __s) : Observer(__n, __s)
    {

    }

    ~NBAObserver()
    {
        if (m_pSub)
        {
            delete m_pSub;
            m_pSub = NULL;
        }
    }

    virtual void Update()
    {
        string strRet = m_pSub->GetSubjectAction();
        printf("%s %s 关闭股票行情,继续工作!\n", strRet.c_str(), m_strName.c_str());
    }
};
#endif // !__NBAOBSERVER__H__
#ifndef  __STOCKOBSERVER__H__
#define  __STOCKOBSERVER__H__

#include "Observer.h"
#include "Subject.h"
#include <stdio.h>

class StockObserver : public Observer
{
public:
    StockObserver(string __n, Subject* __s) : Observer(__n, __s)
    {

    }

    ~StockObserver()
    {
        if (m_pSub)
        {
            delete m_pSub;
            m_pSub = NULL;
        }
    }

    virtual void Update()
    {
        printf("%s %s 关闭股票行情,继续工作!\n", m_pSub->GetSubjectAction().c_str(), m_strName.c_str() );
    }
};
#endif //!__STOCKOBSERVER
//客户端代码
#include <windows.h>
#include <tchar.h>
#include "NBAObserver.h"
#include "StockObserver.h"
#include "Boss.h"
#include "Secretary.h"

int _tmain(int argc, TCHAR* argv[])
{
    //未利用委托

    Boss *pbWang = new Boss();

    Observer * pStock = new StockObserver("Mr Wang", pbWang);
    Observer * pNBA = new NBAObserver("Mrs Yu", pbWang);

    pbWang->Attach(pStock);
    pbWang->Attach(pNBA);
    pbWang->SetSubjectAction("Boss Mr Wang come back");
    pbWang->Notify();

    printf("\n\n*****************\n\n");

    pbWang->Detach(pStock);
    pbWang->Notify();

    if (pbWang)
    {
        delete pbWang;
        pbWang = NULL;
    }

    //利用委托

    return 0;
}

运行结果:
这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章