觀察者模式:定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。它還有兩個別名,依賴(Dependents),發佈-訂閱(Publish-Subsrcibe)。可以舉個博客訂閱的例子,當博主發表新文章的時候,即博主狀態發生了改變,那些訂閱的讀者就會收到通知,然後進行相應的動作,比如去看文章,或者收藏起來。博主與讀者之間存在種一對多的依賴關係。下面給出相應的UML圖設計。
可以看到博客類中有一個觀察者鏈表(即訂閱者),當博客的狀態發生變化時,通過Notify成員函數通知所有的觀察者,告訴他們博客的狀態更新了。而觀察者通過Update成員函數獲取博客的狀態信息。代碼實現不難,下面給出C++的一種實現。
- //觀察者
- class Observer
- {
- public:
- Observer() {}
- virtual ~Observer() {}
- virtual void Update() {}
- };
- //博客
- class Blog
- {
- public:
- Blog() {}
- virtual ~Blog() {}
- void Attach(Observer *observer) { m_observers.push_back(observer); } //添加觀察者
- void Remove(Observer *observer) { m_observers.remove(observer); } //移除觀察者
- void Notify() //通知觀察者
- {
- list<Observer*>::iterator iter = m_observers.begin();
- for(; iter != m_observers.end(); iter++)
- (*iter)->Update();
- }
- virtual void SetStatus(string s) { m_status = s; } //設置狀態
- virtual string GetStatus() { return m_status; } //獲得狀態
- private:
- list<Observer* > m_observers; //觀察者鏈表
- protected:
- string m_status; //狀態
- };
以上是觀察者和博客的基類,定義了通用接口。博客類主要完成觀察者的添加、移除、通知操作,設置和獲得狀態僅僅是一個默認實現。下面給出它們相應的子類實現。
- //具體博客類
- class BlogCSDN : public Blog
- {
- private:
- string m_name; //博主名稱
- public:
- BlogCSDN(string name): m_name(name) {}
- ~BlogCSDN() {}
- void SetStatus(string s) { m_status = "CSDN通知 : " + m_name + s; } //具體設置狀態信息
- string GetStatus() { return m_status; }
- };
- //具體觀察者
- class ObserverBlog : public Observer
- {
- private:
- string m_name; //觀察者名稱
- Blog *m_blog; //觀察的博客,當然以鏈表形式更好,就可以觀察多個博客
- public:
- ObserverBlog(string name,Blog *blog): m_name(name), m_blog(blog) {}
- ~ObserverBlog() {}
- void Update() //獲得更新狀態
- {
- string status = m_blog->GetStatus();
- cout<<m_name<<"-------"<<status<<endl;
- }
- };
- //測試案例
- int main()
- {
- Blog *blog = new BlogCSDN("wuzhekai1985");
- Observer *observer1 = new ObserverBlog("tutupig", blog);
- blog->Attach(observer1);
- blog->SetStatus("發表設計模式C++實現(15)——觀察者模式");
- blog->Notify();
- delete blog; delete observer1;
- return 0;
- }