觀察者模式 c++

觀察者模式
定義:也叫發佈訂閱模式,定義對象間一對多的依賴關係,使得每當一個對象改變(被觀察者(韓非子)),則所有依賴於它的對象(觀察者)都會得到通知並被自動更新。

通用類圖:
這裏寫圖片描述

Subject被觀察者
定義被觀察者必須實現的職責,它必須能夠動態的增加,取消觀察者。它一般是抽象類或者實現類,僅僅完成作爲被觀察者必須實現的職責:管理觀察者並通知觀察者。
Observer觀察者
觀察者接收到消息後,即update操作,對接收到的信息進行處理。
ConcreteSubject具體的被觀察者
定義被觀察者自己的業務邏輯,同時定義對哪些事件進行通知。
ConcreteObserver具體的觀察者
每個觀察者在接收到消息後的處理反應是不同的,各個觀察者有自己的處理邏輯。

模式優點:觀察者與被觀察者之間是抽象耦合,如此設計,不管增加誰都是非常容易的。
建立一套觸發機制。
模式缺點:一個被觀察者,多個觀察者調試比較困難。(一般採用異步的方式)

使用場景:關聯行爲場景;事件多級觸發;跨系統的消息交換場景;

具體場景:
文件系統:例如在一個目錄下建立一個文件,這個動作同時通知目錄管理器增加該目錄,並通知磁盤管理器減少1KB空間.文件時被觀察者,其他倆是觀察者。
ATM機:比如你在ATM上取錢,多次輸錯密碼,卡就會被ATM吞掉,這時,會觸發哪些事件呢?1,攝像頭連拍;2,通知監控系統;3,初始化ATM;一般前兩個動作是觀察者模式來完成的,後一個動作是異常來完成的。

題示:
李斯,等人監控韓非子
類圖:
這裏寫圖片描述

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//觀察者接口
class Observer
{
    public:
    virtual void update(string context)  = 0;

};
//具體觀察者
class LiSi:public Observer
{
public:
    void update(string str)
    {
        cout<<"觀察到韓非子開始活動"<<endl;
        this->reportToQiShiHuang(str);
        cout<<"彙報完畢"<<endl;
    }

    void reportToQiShiHuang(string reportContext)
    {
        cout<<"韓非子有活動了:   "<<reportContext<<endl;
    }
};
class WangSi:public Observer
{
public:
    void update(string str)
    {
        cout<<"觀察到韓非子開始活動"<<endl;
        this->reportToQiShiHuang(str);
        cout<<"彙報完畢"<<endl;
    }

    void reportToQiShiHuang(string reportContext)
    {
        cout<<"韓非子有活動了:   "<<reportContext<<endl;
    }
};

//被觀察者接口
class IHanFeiZi
{
public:
    virtual void haveBreakfast() = 0 ;
    virtual void haveFun()= 0 ;
};
//被觀察者接口
class Observable
{
    public:
    virtual void addObserver(Observer *observer) = 0;//增加觀察者
    virtual void deleteObserver(Observer *observer) = 0 ;//刪除觀察者
    virtual void notifyObserver(string context) = 0 ; //發生改變他應該有所動作通知觀察者
};
//被觀察者實現類
class HanFeiZi : public Observable,IHanFeiZi
{
    private:
    //定義一個變長數組,存放所有觀察者
    vector<Observer*>observerList;
    public:
        void addObserver(Observer *observer)
        {
            this->observerList.push_back(observer);
        }
        void deleteObserver(Observer *observer)
        {
            vector<Observer*>::iterator key = find(observerList.begin(),observerList.end(),observer);
              /*for(; key != observerList.end() ; key++)
              {
                  Observer * keyPtr = *key;
                  if(*keyPtr == *observer)
                        break;
              }*/
              observerList.erase(key);
        }
        void notifyObserver(string context)
        {
            for(auto key : observerList)
                key->update(context);
        }

        void haveBreakfast()
        {
            cout<<"韓非子吃飯了"<<endl;
            //通知所有觀察者
            this->notifyObserver("韓非子在吃飯");
        }
          void haveFun()
        {
            cout<<"韓非子在娛樂"<<endl;
            //通知所有觀察者
            this->notifyObserver("韓非子在娛樂");
        }
};

int main()
{
    Observer *liSi = new LiSi();
    Observer *wangSi = new WangSi();

    HanFeiZi hanfeizi;

    hanfeizi.addObserver(liSi);
    hanfeizi.addObserver(wangSi);

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