欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++設計模式之觀察者模式

 更新時間:2014年10月09日 09:15:37   作者:果凍想  
這篇文章主要介紹了C++設計模式之觀察者模式,本文講解了什么是觀察者模式、觀察者模式的UML類圖、觀察者模式的使用場合等內容,需要的朋友可以參考下

前言

之前做了一個性能測試的項目,就是需要對現(xiàn)在的產品進行性能測試,獲得測試數(shù)據(jù),然后書寫測試報告,并提出合理化的改善意見。項目很簡單,我們獲得了一系列性能測試數(shù)據(jù),對于數(shù)據(jù),我們需要在Excel中制作測試數(shù)據(jù)的折線圖、餅狀圖和柱狀圖,以直觀的表現(xiàn)出性能的變化。在實際操作時,我發(fā)現(xiàn),如果我修改了一個數(shù)據(jù),折線圖、餅狀圖和柱狀圖就都發(fā)生了變換。這個是如何做到的?這就要說到今天總結的觀察者模式了,作為設計模式大家庭中最重要的一個,我們不得不去好好的學習一下觀察者模式。

觀察者模式

在GOF的《設計模式:可復用面向對象軟件的基礎》一書中對觀察者模式是這樣說的:定義對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。當一個對象發(fā)生了變化,關注它的對象就會得到通知;這種交互也稱為發(fā)布-訂閱(publish-subscribe)。目標是通知的發(fā)布者,它發(fā)出通知時并不需要知道誰是它的觀察者。

再說說上面的數(shù)據(jù)和圖之間的關系;不管是折線圖、餅狀圖,還是柱狀圖,它們都依賴于數(shù)據(jù);當數(shù)據(jù)發(fā)生變化時,數(shù)據(jù)對象會通知依賴于它的對象去更新;所以就有了Excel中,當數(shù)據(jù)發(fā)生變化時,對應的統(tǒng)計圖也會自動的重繪。

UML類圖

Subject(目標)
——目標知道它的觀察者??梢杂腥我舛鄠€觀察者觀察同一個目標;
——提供注冊和刪除觀察者對象的接口。

Observer(觀察者)
——為那些在目標發(fā)生改變時需獲得通知的對象定義一個更新接口。

ConcreteSubject(具體目標)
——將有關狀態(tài)存入各ConcreteObserver對象;
——當它的狀態(tài)發(fā)生改變時,向它的各個觀察者發(fā)出通知。

ConcreteObserver(具體觀察者)
——維護一個指向ConcreteSubject對象的引用;
——存儲有關狀態(tài),這些狀態(tài)應與目標的狀態(tài)保持一致;
——實現(xiàn)Observer的更新接口以使自身狀態(tài)與目標的狀態(tài)保持一致。

觀察者模式按照以下方式進行協(xié)作:

1.當ConcreteSubject發(fā)生任何可能導致其觀察者與其本身狀態(tài)不一致的改變時,它將通知它的各個觀察者;

2.在得到一個具體目標的改變通知后,ConcreteObserver對象可向目標對象查詢信息。ConcreteObserver使用這些信息以使它的狀態(tài)與目標對象的狀態(tài)一致。

以下是調用時序圖:

使用場合

在以下任一情況下都可以使用觀察者模式:

1.當一個抽象模型有兩個方面,其中一個方面依賴于另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立的改變和復用;
2.當對一個對象的改變需要同時改變其它對象,而不知道具體有多少對象有待改變;
3.當一個對象必須通知其它對象,而它又不能假定其它對象是誰;也就是說,你不希望這些對象是緊密耦合的。

代碼實現(xiàn)

復制代碼 代碼如下:

#include <iostream>
#include <list>
using namespace std;
 
class Observer
{
public:
     virtual void Update(int) = 0;
};
 
class Subject
{
public:
     virtual void Attach(Observer *) = 0;
     virtual void Detach(Observer *) = 0;
     virtual void Notify() = 0;
};
 
class ConcreteObserver : public Observer
{
public:
     ConcreteObserver(Subject *pSubject) : m_pSubject(pSubject){}
 
     void Update(int value)
     {
          cout<<"ConcreteObserver get the update. New State:"<<value<<endl;
     }
 
private:
     Subject *m_pSubject;
};
 
class ConcreteObserver2 : public Observer
{
public:
     ConcreteObserver2(Subject *pSubject) : m_pSubject(pSubject){}
 
     void Update(int value)
     {
          cout<<"ConcreteObserver2 get the update. New State:"<<value<<endl;
     }
 
private:
     Subject *m_pSubject;
};
 
class ConcreteSubject : public Subject
{
public:
     void Attach(Observer *pObserver);
     void Detach(Observer *pObserver);
     void Notify();
 
     void SetState(int state)
     {
          m_iState = state;
     }
 
private:
     std::list<Observer *> m_ObserverList;
     int m_iState;
};
 
void ConcreteSubject::Attach(Observer *pObserver)
{
     m_ObserverList.push_back(pObserver);
}
 
void ConcreteSubject::Detach(Observer *pObserver)
{
     m_ObserverList.remove(pObserver);
}
 
void ConcreteSubject::Notify()
{
     std::list<Observer *>::iterator it = m_ObserverList.begin();
     while (it != m_ObserverList.end())
     {
          (*it)->Update(m_iState);
          ++it;
     }
}
 
int main()
{
     // Create Subject
     ConcreteSubject *pSubject = new ConcreteSubject();
 
     // Create Observer
     Observer *pObserver = new ConcreteObserver(pSubject);
     Observer *pObserver2 = new ConcreteObserver2(pSubject);
 
     // Change the state
     pSubject->SetState(2);
 
     // Register the observer
     pSubject->Attach(pObserver);
     pSubject->Attach(pObserver2);
 
     pSubject->Notify();
 
     // Unregister the observer
     pSubject->Detach(pObserver);
 
     pSubject->SetState(3);
     pSubject->Notify();
 
     delete pObserver;
     delete pObserver2;
     delete pSubject;
}

總結

觀察者模式在23個設計模式中的地位是非常高的,我們基本上各大框架中都是隨處可見。真正的理解了整個模式,對我們去理解別人的代碼有非常大的幫助;在我們日后的工作中也會或多或少的使用該設計模式。這里總結的不是很全面,在日后如果碰到了需要補充的內容,我會繼續(xù)補充的;同時也希望大家提出更好的建議。

相關文章

  • 電腦開機時間的計算代碼

    電腦開機時間的計算代碼

    這幾天我琢磨著一件事,那就是怎么計算我的PC從開機到現(xiàn)在的總時間。終于,看看這個函數(shù):GetTickCount();
    2013-05-05
  • C++制作鼠標連點器實例代碼

    C++制作鼠標連點器實例代碼

    大家好,本篇文章主要講的是C++制作鼠標連點器實例代碼,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • static_cast,dynamic_cast,reinterpret_cast,const_cast的區(qū)別及用法詳解

    static_cast,dynamic_cast,reinterpret_cast,const_cast的區(qū)別及用法詳解

    以下是對static_cast,dynamic_cast,reinterpret_cast,const_cast的區(qū)別及用法進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-09-09
  • 推薦幾款C/C++的編譯器、編譯環(huán)境(非常全面的比較)

    推薦幾款C/C++的編譯器、編譯環(huán)境(非常全面的比較)

    這篇文章主要介紹了C/C++編譯器的一些易混淆概念,這里腳本之家小編特為大家分享一下,需要的朋友可以參考下
    2021-06-06
  • C語言輕松實現(xiàn)掃雷小游戲

    C語言輕松實現(xiàn)掃雷小游戲

    掃雷是一款經典的小游戲,這篇文章主要為大家詳細介紹了C語言輕松實現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C++?構造函數(shù)學習筆記

    C++?構造函數(shù)學習筆記

    這篇文章主要為大家介紹了C++?構造函數(shù)學習筆記,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • C++ 多線程編程建議之 C++ 對多線程/并發(fā)的支持(下)

    C++ 多線程編程建議之 C++ 對多線程/并發(fā)的支持(下)

    這篇文章主要介紹的是 C++ 多線程編程建議之 C++ 對多線程/并發(fā)的支持的相關資料,承接前文 現(xiàn)代 C++ 對多線程/并發(fā)的支持,接下來我們看看回發(fā)生什么吧
    2021-10-10
  • 淺談C++ Socket編程

    淺談C++ Socket編程

    本文給大家簡單介紹了C++中的Socket編程的種類以及sockets編程的8個步奏,簡單生動,有需要的小伙伴可以參考下
    2017-07-07
  • C++中char*轉換為LPCWSTR的解決方案

    C++中char*轉換為LPCWSTR的解決方案

    最近在學習C++,遇到了一個char*轉換為LPCWSTR的問題,通過查找資料終于解決了,所以下面這篇文章主要介紹了C++中char*轉LPCWSTR的解決方案,文中通過詳細的示例代碼介紹的很詳細,有需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01
  • C++代碼實現(xiàn)鏈隊列詳解

    C++代碼實現(xiàn)鏈隊列詳解

    下面小編就為大家分享一篇C++代碼實現(xiàn)鏈隊列的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧,希望能夠給你帶來幫助
    2021-09-09

最新評論