設計模式 研究 觀察者模式 有時間跟新上來

2021-05-21 18:50:51 字數 4656 閱讀 8208

subject  -  目標

oberver -  觀察者

concretesubject - 具體目標

concreteobserver - 具體觀察者

過去一直對設計模式 虎視眈眈, 終於有機會可以 整理一下設計模式 自己用工程的框架實現它,google 了好多

blog  神秘果的寫的不錯,深入淺出 易於理解,大家可以google下, code 是那種的乙個改進,同時我也在看設計

模式這本書, 已經看了3遍了 ,還是菜鳥,這次是細細的看,每個模式都要用sdk實現以下,深入理解下,

這裡用的乙個rtti 特性,我用 一種全域性識別符號 表示類的一種,別笑話,這僅僅是研究,mfc使用的時候,會使用rtti

聽說效能有損失,爭取不用這個特性,

observer(觀察者)

1. 意圖 定義物件的一種一對多的依賴關係,當乙個物件的狀態發生改變時,所有依賴它的物件都得到通知並被自動更新

2,別名

依賴( dependents), (發布-訂閱) (publish - subscribe)

3. 動 機 -

將乙個系統分割成一系列相互協作的類有乙個常見的***,需要維護相關物件間的一致性。我們不希望為了維護一致性而

使各類緊密耦合,因為這樣會降低他們的可重用性

關鍵物件 目標 和 觀察者

乙個目標可以有任意數目的依賴它的觀察者。一旦目標的狀態發生改變,所有的觀察者都得到通知

作為對這個通知的響應,每個觀察者都將查詢目標以使其狀態與目標的狀態同步 

我覺得設計模式這個地方寫的夠臃腫的,看他反而容易看不明白,呵呵 

下面(理解和要點)這些,來自神秘果的摘錄:

理解

1.       觀察者模式建立目標(subject)和觀察者(observer)之間的協作關係。目標和觀察者是1:n的關係。1個目標可以有n個依賴它的觀察者。當目標狀態發生變化時,n個觀察者要得到通知,以便更新狀態。

2.       目標(subject)儲存了所有依賴它的觀察者物件的指標。目標提供了註冊(attach)和登出(detach)觀察者的介面。註冊後,觀察者就可以得到目標狀態變化的通知。

3.       觀察者(observer)只提供了接收目標通知的更新介面。

4.       具體目標(concretesubject)發生與觀察者的狀態不一致時,通知(notify)介面呼叫觀察者的更新(update)介面。

要點

1.       目標物件僅僅儲存了觀察者類介面的指標,因此不是緊耦合的。目標不用關心是觀察者是誰。

2.       目標物件狀態發生變化時,僅僅通過廣播方式通知所有註冊的觀察者。觀察者可以自由決定是否忽略目標物件的通知。

3.       觀察多個目標。乙個觀察者可能需要觀察多個目標物件。觀察者的update介面需要擴充套件引數,目標物件把自己作為update介面的引數,讓觀察者知道去檢查哪乙個目標。

4.       誰呼叫notify介面。目標物件發生變化時,自動呼叫notify介面;也可以是觀察者根據清空自己選擇實際呼叫notify介面。前者簡單但可能效率低;後者可避免重複更新,但觀察者可能忘記呼叫notify,導致狀態不一致。

5.       推/拉模式。目標狀態變化,通知所有的觀察者,稱為推模式;由觀察者主動詢問目標的狀態是否變化來決定是否更新的方式,稱為拉模式。兩種模式決定了notify由誰呼叫。

**還是我自己乙個字母乙個字母敲打滴  呵呵

讓我們開始一步步的實現

開啟vc6, 建立乙個win32 空白的console 工程,新增檔案 

obsmain.cpp

#include

//#pragma   warning(default:4786)  //開啟4786

#pragma warning(disable: 4786)

#include "cbloger.h"

#include "cportal.h"

#include "crssreader.h"

#include "cmailreader.h"

using namespace std;

int main(int argc, char *argv)

//目標,被觀察者

cbloger *pblog = new cbloger();

cportal *pportal =  new cportal();

crssreader *prssreader = new crssreader("rss reader");

cmailreader *pmailreader = new cmailreader("mail reader");

pblog->attach(prssreader);  //bloger註冊觀察者  

pblog->attach(pmailreader); //bloger註冊觀察者

// pportal->attach(pmailreader);//portal註冊觀察者

// pportal->attach(prssreader);//portal註冊觀察者

pblog->publish("部落格分享設計模式");  //部落格發布資訊

// pportal->publish("門戶分享設計模式"); //門戶發布資訊

pblog->detach(prssreader); // blog登出觀察者

pblog->publish("eagle 更新完整版本");

cout << "blog 觀察者數量" << pblog->getobserverscounts() << endl;

cout << "portal 觀察者數量" << pportal->getobserverscounts() << endl;

if ( prssreader != null )

delete prssreader;

if ( pmailreader != null )

delete pmailreader;

if ( pblog != null )

delete pblog;

if ( pportal != null)

delete pportal;

return 0;

// 新增檔案 observer

#ifndef _h_h_observableh_h_

#define _h_h_observableh_h_

#include "cobserver.h"

#include

using namespace std;

//被觀察者, 就是subject

class csubject

public:

csubject():m_bchanged(false){}

virtual ~csubject(){}

//註冊觀察者

void attach(cobserver* pobjs);

//登出觀察者

void detach(cobserver* pobjs);

// 登出所有觀察者

void detachall();

//測試目標狀態是不是變化

bool haschanged();

//如果狀態變化,遍歷所有觀察者,逐個通知更新

void notify(void* parg = null);

//得到觀察者的數量

int getobserverscounts();

void setclasstypeid(int ctid);

int getclasstypeid(void);

//getdata(); 設計乙個runtime_class 參照mfc,可以判斷是那個被觀察者型別

protected:

//初始化目標未變化狀態

void clearchanged();

//設定狀態變化, !!!注意!!!必須繼承了cobservable 才能設定目標狀態

void setchanged();

private:

bool m_bchanged; //狀態

setm_setobs; //set保證目標的唯一性

int m_itypeid;

#endif

// 新增檔案 

#ifndef _h_h_observer_h_h_

#define _h_h_observer_h_h_

#include

#include

using namespace std;

//抽象模式定義

class csubject;

//觀察者,純虛基類

class cobserver

public:

cobserver();

virtual ~cobserver();

//當被觀察的目標發生變化時, 通知呼叫該方法

//來自被觀察者pobs, 擴充套件引數parg

virtual void update(csubject *pobs, void *parg = null)=0; 

#endif

每個類乙個檔案,這樣以後擴充套件起來 方便 ,  工程將來壓縮上傳到 http://d.download.csdn.net/down/2049698/dove1980

python 設計模式 觀察者 觀察者設計模式

在觀察者設計模式這種模式中,物件被表示為等待事件觸發的觀察者。一旦發生指定的事件,觀察者就會關注該主體。當事件發生時,主體告訴觀察者它已經發生。以下uml圖表示觀察者模式 如何實現觀察者模式?現在讓我們來看看如何實現觀察者模式。參考以下實現 import threading import time ...

設計模式 觀察者模式

觀察者模式定義了物件間一對多的依賴關係,乙個物件發生變化時,所有依賴它的物件都得到通知並被自動更新。本文主要闡述觀察者模式在分布式scada人機介面中的使用,利用這種模式使得人機介面顯示效率更高。發布者 郵局 觀察者 參與者 讀者 訂閱者 當郵局收到報社新雜誌的時候,即郵局狀態發生了改變,於是郵局把...

設計模式 觀察者模式

核心思想 註冊 通知 撤銷註冊 observer 將自己註冊到被觀察物件 subject 中,被觀察物件將觀察者存放在乙個容器 container 裡。被觀察物件發生了某種變化 如圖中的somechange 從容器中得到所有註冊過的觀察者,將變化通知觀察者。觀察者告訴被觀察者要撤銷觀察,被觀察者從容...