Observer觀察者模式
做用:觀察者模式定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態發生變化時,會通知全部觀察者對象,使它們可以自動更新本身ios
UML圖:this
Subject類,可翻譯爲主題或抽象通知者,通常用一個抽象類或者一個藉口實現。它把全部對觀察者對象的引用保存在一個彙集裏,每一個主題均可以有任何數量的觀察者。抽象主題提供一個藉口,能夠增長和刪除觀察者對象。spa
Observer類,抽象觀察者,爲全部的具體觀察者定義一個藉口,在獲得主題的通知時更新本身。這個藉口叫作更新接口。抽象觀察者通常用一個抽象類或者一個接口實現。更新接口一般包含一個Update()方法。
ConcreteSubject類,叫作具體主題或具體通知者,將有關狀態存入具體通知者對象;在具體主題的內部狀態改變時,給全部等級過的觀察者發出通知。一般用一個具體子類實現。翻譯
ConcreteObserver類,具體觀察者,實現抽象觀察者角色所要求的更新接口,以便使自己的狀態與主題的狀態相協調。具體觀察者角色能夠保存一個指向一個具體主題對象的引用。
特色:將一個系統分割成一系列相互協做的類有一個很很差的反作用,那就是須要維護相關對象間的一致性。咱們不但願爲了維持一致性而使各種緊密耦合,這樣會給維護、擴展和重用都帶來不便。
什麼時候使用:
當一個對象的改變須要同時改變其餘對象的時候,並且它不知道具體有多少對象有待改變時,應該考慮使用觀察者模式。
觀察者模式所作的工做其實就是在解除耦合。讓耦合的雙方都依賴於抽象,而不是依賴於具體。從而使得各自的變化都不會影響另外一邊的變化。code
代碼以下:server
Observer.h對象
1 #ifndef _OBSERVER_H_ 2 #define _OBSERVER_H_ 3 4 #include <string> 5 #include <list> 6 using namespace std; 7 8 class Subject; 9 10 class Observer 11 { 12 public: 13 ~Observer(); 14 virtual void Update(Subject*)=0; 15 protected: 16 Observer(); 17 private: 18 }; 19 20 class ConcreteObserverA : public Observer 21 { 22 public: 23 ConcreteObserverA(); 24 ~ConcreteObserverA(); 25 virtual void Update(Subject*); 26 protected: 27 private: 28 string m_state; 29 }; 30 31 class ConcreteObserverB : public Observer 32 { 33 public: 34 ConcreteObserverB(); 35 ~ConcreteObserverB(); 36 virtual void Update(Subject*); 37 protected: 38 private: 39 string m_state; 40 }; 41 42 class Subject 43 { 44 public: 45 ~Subject(); 46 virtual void Notify(); 47 virtual void Attach(Observer*); 48 virtual void Detach(Observer*); 49 virtual string GetState(); 50 virtual void SetState(string state); 51 protected: 52 Subject(); 53 private: 54 string m_state; 55 list<Observer*> m_lst; 56 }; 57 58 class ConcreteSubjectA : public Subject 59 { 60 public: 61 ConcreteSubjectA(); 62 ~ConcreteSubjectA(); 63 protected: 64 private: 65 }; 66 67 class ConcreteSubjectB : public Subject 68 { 69 public: 70 ConcreteSubjectB(); 71 ~ConcreteSubjectB(); 72 protected: 73 private: 74 }; 75 76 #endif
Observer.cppblog
1 #include "Observer.h" 2 #include <iostream> 3 #include <algorithm> 4 5 using namespace std; 6 7 Observer::Observer() 8 {} 9 10 Observer::~Observer() 11 {} 12 13 ConcreteObserverA::ConcreteObserverA() 14 {} 15 16 ConcreteObserverA::~ConcreteObserverA() 17 {} 18 19 void ConcreteObserverA::Update(Subject* pSubject) 20 { 21 this->m_state = pSubject->GetState(); 22 cout << "The ConcreteObserverA is " << m_state << std::endl; 23 } 24 25 ConcreteObserverB::ConcreteObserverB() 26 {} 27 28 ConcreteObserverB::~ConcreteObserverB() 29 {} 30 31 void ConcreteObserverB::Update(Subject* pSubject) 32 { 33 this->m_state = pSubject->GetState(); 34 cout << "The ConcreteObserverB is " << m_state << std::endl; 35 } 36 37 Subject::Subject() 38 {} 39 40 Subject::~Subject() 41 {} 42 43 void Subject::Attach(Observer* pObserver) 44 { 45 this->m_lst.push_back(pObserver); 46 cout << "Attach an Observer\n"; 47 } 48 49 void Subject::Detach(Observer* pObserver) 50 { 51 list<Observer*>::iterator iter; 52 iter = find(m_lst.begin(),m_lst.end(),pObserver); 53 if(iter != m_lst.end()) 54 { 55 m_lst.erase(iter); 56 } 57 cout << "Detach an Observer\n"; 58 } 59 60 void Subject::Notify() 61 { 62 list<Observer*>::iterator iter = this->m_lst.begin(); 63 for(;iter != m_lst.end();iter++) 64 { 65 (*iter)->Update(this); 66 } 67 } 68 69 string Subject::GetState() 70 { 71 return this->m_state; 72 } 73 74 void Subject::SetState(string state) 75 { 76 this->m_state = state; 77 } 78 79 ConcreteSubjectA::ConcreteSubjectA() 80 {} 81 82 ConcreteSubjectA::~ConcreteSubjectA() 83 {} 84 85 ConcreteSubjectB::ConcreteSubjectB() 86 {} 87 88 ConcreteSubjectB::~ConcreteSubjectB() 89 {}
main.cpp接口
#include "Observer.h" #include <iostream> using namespace std; int main() { Observer* p1 = new ConcreteObserverA(); Observer* p2 = new ConcreteObserverB(); Observer* p3 = new ConcreteObserverA(); Subject* pSubject = new ConcreteSubjectA(); pSubject->Attach(p1); pSubject->Attach(p2); pSubject->Attach(p3); pSubject->SetState("old"); pSubject->Notify(); cout << "-------------------------------------" << endl; pSubject->SetState("new"); pSubject->Detach(p3); pSubject->Notify(); return 0; }
結果以下:string