C++設計模式之觀察者模式(Observer)
觀察者模式通常的叫法叫做訂閱-發(fā)布模式,類似于報刊雜志的訂閱,觀察者和被觀察者就是讀者和郵局的關系,讀者先要在郵局訂閱想要的報刊,當報刊發(fā)行時,郵局會將報刊郵寄到讀者家里。觀察者(Observer)和被觀察者(Listener)也是這種關系,Observer將自己attach到Listener中,當Listener觸發(fā)時Notify所有Observer.
作用
在觀察者模式中,被觀察者維護觀察者對象的集合,當被觀察者對象變化時,它會通知觀察者。觀察者模式主要是用于解決對象之間一對多的關系。
類視圖
實現
class Observer { public: virtual ~Observer() {}; virtual void Update(const std::string &msg)= 0; protected: Observer(){}; }; class Listener { public: virtual ~Listener() {}; void attach(Observer* obsvr) { m_observers.push_back(obsvr); } void remove(Observer* obsvr) { m_observers.remove(obsvr); } void notify(const std::string &msg) { list<Observer*>::iterator iter = m_observers.begin(); for(; iter != m_observers.end(); iter++) (*iter)->Update(msg); } private: list<Observer* > m_observers; //觀察者鏈表 }; class logRunner : public Listener { public: virtual ~logRunner(){}; void addmsg(const std::string &msg) { nofity(msg); } } class logGui : public Observer { public: virtual ~Observer(){}; void Update(const std::string &msg) { cout<< "Gui log show : "<< msg <<endl; } } class logFile : public Observer { public: virtual ~Observer(){}; void Update(const std::string &msg) { cout<< "file log write : "<< msg <<endl; } } class logDebug : public Observer { public: virtual ~Observer(){}; void Update(const std::string &msg) { cout<< "Debug log out : "<< msg <<endl; } } class logDataBase : public Observer { public: virtual ~Observer(){}; void Update(const std::string &msg) { cout<< "DataBase log in : "<< msg <<endl; } } int main() { logRunner Runner; logGui gGui; logFile gFile; logDebug gDebug; logDataBase gDataBase; Runner.attach(&gGui); Runner.attach(&gFile); Runner.attach(&gDebug); Runner.attach(&gDataBase); Runner.addmsg("app is setup"); }
Observer中update一般為純虛,通過子類各自實現,這里只是保證調用的接口一致,Listener中的attach、remove、notify一般建議不進行虛化,子類不用關心其內部的聚合內容,通過調用notify實現消息分發(fā)即可。當然也可以虛化,將這一系列的操作放到子類進行實現。
調用者應該注意在多線程環(huán)境中的使用環(huán)境,做好數據的同步工作。
應用場景
- 當一個對象改變需要通知到其他對象,而我們不確定由多少對象需要通知時;
- 當一個對象必須通知其他對象,而不需要知道對象是什么實現時;
- 對于一堆對象,包含同樣的狀態(tài)或同樣的數據,通過同一個條件進行更新時。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。