設計模式----觀察者模式 【含例項】
阿新 • • 發佈:2018-11-07
日常學習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