觀察者模式(Observer Pattern) —— 定義對象間的一種一對多的依賴關係,以便當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並自動刷新。ios
觀察者模式能夠理解爲發佈-訂閱模式,即多個訂閱者(觀察者)向發佈者(被觀察者)訂閱狀態信息,當發佈者更新狀態時會將狀態信息向它的訂閱者發佈信息。發佈者須要本身維護訂閱者列表,能夠註冊或者註銷對狀態信息感興趣或不感興趣的訂閱者。this
// subject.h #include<vector> #include<string> using namespace std; typedef int State; class Observer; // 被觀察者(發佈者)抽象 class Subject { public: Subject(){} virtual ~Subject(){} virtual void Attach(Observer* obv); // 註冊觀察者 virtual void Detach(Observer* obv); // 註銷觀察者 virtual void Notify(); // 通知觀察者 virtual void SetState(const State& st) = 0; virtual State GetState() = 0; private: //觀察者列表 vector<Observer*> m_pObs; }; // 被觀察者(實際發佈者) class ConcreteSubject: public Subject { public: ConcreteSubject(){} ~ConcreteSubject(){} State GetState(); void SetState(const State& st); private: State m_state; };
// subject.cpp #include "subject.h" #include "observer.h" void Subject::Attach(Observer* pObs) { m_pObs.push_back(pObs); } void Subject::Detach(Observer* pObs) { vector<Observer*>::iterator it = m_pObs.begin(); for ( ;it!=m_pObs.end();++it) { if (*it == pObs) { m_pObs.erase(it); return; } } } void Subject::Notify() { vector<Observer*>::iterator it = m_pObs.begin(); for ( ; it!=m_pObs.end(); ++it) { (*it)->update(this); } } void ConcreteSubject::SetState(const State& st) { m_state = st; } State ConcreteSubject::GetState() { return m_state; }
// observer.h #include<iostream> #include<string> #include<vector> using namespace std; typedef int State; class Subject; // 觀察者抽象 class Observer { public: Observer(){} virtual ~Observer(){} virtual void update(Subject* sub) = 0; virtual void outputState(); protected: string m_name; State m_observerState; }; // 實際觀察者A class ConcreteObserverA: public Observer { public: ConcreteObserverA(string name, State init_state){ m_name = name; m_observerState = init_state; } ~ConcreteObserverA(){} void update(Subject* sub); private: // Subject* m_sub; }; // 實際觀察者B class ConcreteObserverB: public Observer { public: ConcreteObserverB(string name, State init_state){ m_name = name; m_observerState = init_state; } ~ConcreteObserverB(){} void update(Subject* sub); private: // Subject* m_sub; };
// observer.cpp #include "observer.h" #include "subject.h" void Observer::outputState() { cout<<m_name<<" update state :"<<m_observerState<<endl; } void ConcreteObserverA::update(Subject* sub) { m_observerState = sub->GetState(); outputState(); } void ConcreteObserverB::update(Subject* sub) { m_observerState = sub->GetState(); outputState(); }
// main.cpp #include "observer.h" #include "subject.h" int main() { ConcreteSubject* subject = new ConcreteSubject(); Observer* obA = new ConcreteObserverA("observerA", -1); Observer* obB = new ConcreteObserverB("observerB", -1); subject->Attach(obA); subject->Attach(obB); subject->SetState(0); subject->Notify(); subject->Detach(obA); subject->SetState(1); subject->Notify(); delete obA; delete obB; delete subject; return 0; } // 輸出結果: //observerA update state :0 //observerB update state :0 //observerB update state :1