1. 程式人生 > >設計模式----觀察者模式 【含例項】

設計模式----觀察者模式 【含例項】

日常學習C++設計模式中...

給自己留個備份,有問題歡迎溝通交流。

好了,開始嘍~

-------------------------------------------------------------------------------------------------------------------

需求

  當某物件狀態改變時,需要通知多個物件進行更新,即一對多依賴關係。

  例如:某家公司的旅遊基金漲了,每個人都漲了500!!,那麼員工需要重新計算獲得的旅遊基金總額,重新安排自己的旅遊規劃,那麼這些員工就是觀察者,公司將漲500通知到每個員工,員工各自處理。【舉得不知道合不合適。。】

分析

   多個物件,即觀察者,對某物件的狀態進行監聽。

原始碼

//main.h
#ifndef MAIN_H
#define MAIN_H
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <list>
#include <string>
#include <algorithm>

class IObserver;
/////////////create ABC /////////////////
class IManager{
public:
    IManager(){}

    virtual void registerObservers(IObserver* obv) = 0;
    virtual void unRegisterObservers(IObserver* obv) = 0;

    //callback data to Observers
    virtual void callbackData(std::string data) = 0;
};

class IObserver{
public:
    IObserver(){}

    //recive data from Manager
    virtual void updateData(std::string data) = 0;

};

////////create IManager son class/////////
class Manager: public IManager
{
public:
    virtual void registerObservers(IObserver* obv);
    virtual void unRegisterObservers(IObserver* obv);
    virtual void callbackData(std::string data);

private:
    std::list<IObserver* > m_registerObvList;
};

////////create  Observers////////////
class Observer_1 :public IObserver
{
public:
    Observer_1(std::string id){m_id = id;}

    //recive data from Manager
    virtual void updateData(std::string data);

private:
    std::string m_id;
};

class Observer_2:public IObserver
{
public:
    Observer_2(std::string id){m_id = id;}

    //recive data from Manager
    virtual void updateData(std::string data);

private:
    std::string m_id;
};


#endif // MAIN_H
//main.cpp
#include "main.h"

//////////觀察者模式////////////
void Manager::registerObservers(IObserver* obv)
{
    if(NULL != obv)
    {
        m_registerObvList.push_back(obv);
    }
}

void Manager::unRegisterObservers(IObserver* obv)
{
    std::list<IObserver*>::iterator iter;
    iter = std::find(m_registerObvList.begin(),m_registerObvList.end(),obv);
    if(m_registerObvList.end() != iter)
    {
        m_registerObvList.erase(iter);
    }
}

void Manager::callbackData(std::string data)
{
    std::list<IObserver*>::iterator iter;
    for(iter = m_registerObvList.begin(); iter != m_registerObvList.end(); ++iter)
    {
        (*iter)->updateData(data); //pass data to all observers
    }
}

void Observer_1::updateData(std::string data)
{
    printf("----->[Observer_1]updateData data:%s\n",data.c_str());
}

void Observer_2::updateData(std::string data)
{
    printf("----->[Observer_2]updateData data:%s\n",data.c_str());
}

int main(int argc, char *argv[])
{
    printf("========hello======\n");

    //建立Manager
    IManager* manager = new Manager();
    //建立觀察者1號,2號
    IObserver* obv1 = new Observer_1("A");
    IObserver* obv2 = new Observer_1("B");

    //註冊
    manager->registerObservers(obv1);
    manager->registerObservers(obv2);

    printf("-------start callback data--------\n");
    //向已註冊的所有觀察者傳遞資料
    manager->callbackData("Hello Wantong!");

    return 0;
}

輸出結果

========hello======
-------start callback data--------
----->[Observer_1]updateData data:Hello Wantong!
----->[Observer_1]updateData data:Hello Wantong!

總結

從輸出結果可以看出,兩個觀察者均收到了來自IManager的資料,並分別列印。

使用時,當然可以每個觀察者物件收到資料時,可以進行完全不同的操作,不限制於列印log。

 

感謝網上各路大神的分享。

學習參考 https://me.csdn.net/u011012932