觀察者模式(obsever pattern)又名發行/訂閱模式(publish-subscribe pattern),是事件驅動模型的簡化版本,也是咱們熟知的MVC架構的核心部分。ios
下面以博客園訂閱博客爲例,窺探一下觀察者模式蘊含的奧祕:設計模式
當博主發表新文章的時候,即博主狀態發生了改變,那些訂閱的讀者就會收到通知,而後進行相應的動做,好比去看文章,或者收藏起來。博主與讀者之間存在種一對多的依賴關係。架構
【對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新】這就是觀察者模式,所謂的觀察者能夠理解爲關注博客的讀者,被觀察的對象(Subject)即爲博主,博主自身狀態發生改變時會發出通知(Notify),讀者(Obsever)能夠經過更新操做(Update)得到博主的最新消息。測試
觀察者模式的實現有如下4類角色:spa
這麼說你們可能還不太理解,結合下面這張圖和實現代碼來分析:設計
觀察者模型所需4大類(obsever.h):code
1 #include <iostream> 2 #include <string> 3 #include <list> 4 #include <iterator> 5 using namespace std; 6 //觀察者 7 class Observer 8 { 9 public: 10 Observer() {} 11 virtual ~Observer() {} 12 virtual void Update() {} 13 }; 14 //博客 15 class Blog 16 { 17 public: 18 Blog() {} 19 virtual ~Blog() {} 20 void Attach(Observer *observer) { m_observers.push_back(observer); } //添加觀察者 21 void Remove(Observer *observer) { m_observers.remove(observer); } //移除觀察者 22 void Notify() //通知觀察者 23 { 24 list<Observer*>::iterator iter = m_observers.begin(); 25 for (; iter != m_observers.end(); iter++) 26 (*iter)->Update(); 27 } 28 virtual void SetStatus(string s) { m_status = s; } //設置狀態 29 virtual string GetStatus() { return m_status; } //得到狀態 30 private: 31 list<Observer* > m_observers; //觀察者鏈表 32 protected: 33 string m_status; //狀態 34 }; 35 36 //具體博客類 37 class CNBlog : public Blog 38 { 39 private: 40 string m_name; //博主名稱 41 public: 42 CNBlog(string name) : m_name(name) {} 43 ~CNBlog() {} 44 void SetStatus(string s) { m_status = "cnblog通知 : " + m_name + s; } //具體設置狀態信息 45 string GetStatus() { return m_status; } 46 }; 47 //具體觀察者 48 class ObserverBlog : public Observer 49 { 50 private: 51 string m_name; //觀察者名稱 52 list<Blog* > m_blog; //訂閱者鏈表 53 public: 54 ObserverBlog(string name) : m_name(name){} 55 ~ObserverBlog() {} 56 void Attach(Blog *blog) { m_blog.push_back(blog); } //添加訂閱者 57 void Remove(Blog *blog) { m_blog.remove(blog); } //移除訂閱者 58 void Update() //得到更新狀態 59 { 60 //爲了防止訂閱者重複輸出所觀察的博客,每次只輸出最後一個博主的更新消息 61 list<Blog*>::iterator iter = m_blog.end(); 62 string status = (*(--iter))->GetStatus(); 63 if (status != "") 64 cout << m_name << "-------" << status << endl; 65 } 66 };
測試代碼:server
1 //測試代碼 2 //3個觀察者,3個訂閱者,第1個觀測者訂閱了一、二、3號訂閱者,第1個訂閱者被一、二、3號觀察者關注。 3 #include "obsever.h" 4 5 int main() 6 { 7 Blog *blog1 = new CNBlog("acelit1"); 8 Blog *blog2 = new CNBlog("acelit2"); 9 Blog *blog3 = new CNBlog("acelit3"); 10 11 ObserverBlog *observer1 = new ObserverBlog("subscriber1"); 12 ObserverBlog *observer2 = new ObserverBlog("subscriber2"); 13 ObserverBlog *observer3 = new ObserverBlog("subscriber3"); 14 15 observer1->Attach(blog1); 16 observer2->Attach(blog1); 17 observer3->Attach(blog1); 18 19 blog1->Attach(observer1); 20 blog1->Attach(observer2); 21 blog1->Attach(observer3); 22 blog1->SetStatus("發表設計模式C++實現——觀察者模式"); 23 blog1->Notify(); 24 25 observer1->Attach(blog2); 26 blog2->Attach(observer1); 27 blog2->SetStatus(" published: observer pattern"); 28 blog2->Notify(); 29 30 observer1->Attach(blog3); 31 blog3->Attach(observer1); 32 blog3->SetStatus(" published: 觀察者模式"); 33 blog3->Notify(); 34 35 delete blog1; 36 delete blog2; 37 delete blog3; 38 delete observer1; 39 delete observer2; 40 delete observer3; 41 42 system("pause"); 43 return 0; 44 }
測試結果:對象
博主acelit1狀態改變,observer1~3均更新狀態;博主acelit2和acelit3狀態改變,只有observer1更新狀態。blog
全文完。歡迎各位老司機批評指正O(∩_∩)O