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;
}

運行結果:
這裏寫圖片描述

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