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 從容器中得到所有註冊過的觀察者,將變化通知觀察者。觀察者告訴被觀察者要撤銷觀察,被觀察者從容...