和以前一樣,在介紹觀察者模式之前,我們先看看如果不用觀察者模式會是怎樣的
首先我們假定以下情景:有乙個資料來源datasource,要分別在三個地方place1,place2,place3這三個地方展示,我們來看看傳統的硬編碼會怎麼做?(因為比較容易,直接給類圖,就不上**了)
這裡定義了datasource,他是這樣工作的:
呼叫setdata改變資料
呼叫updata,其實是呼叫裡面的place物件的updata()
使用這種硬編碼的方式事非常的不優雅的,我們可以看到,依賴關係直接寫死在了**裡,如果要新增乙個展示資料的地方要修改**,如果這個地方不想再接收這個資料了,也需要修改**,這無疑是一件很痛苦的事,接下來我們來改進
先上圖:
subject裡面有乙個註冊方法,用來註冊觀察者,乙個移除方法,用來移除觀察者,乙個notify方法廣播更新,我們來看看原始碼:
//定義主題介面
public
inte***ce subject
public
class
datasource
implements
subject
//當沒有這個物件的時候才能增加,防止重複訂閱
public
void
registobserver(observer observer)
}//當有這個物件才能取消訂閱,防止空指標異常
public
void
removeobserver(observer observer)
}//依次廣播
public
void
notifyobservers()
//改變資料
public
void
setdata(float high, float length, int count)
}
下面是play物件,因為三個演示類**都一樣,我就只放乙個類的實現好了
public
inte***ce observer
public
inte***ce displaydata
public
class
place1
implements
observer,displaydata
public
void
display()
public
void
updata(float high, float length, int count)
}
ok,我們寫個測試類來測試一下
public
class main
}結果如下:
這裡是一號位置!hight=1.0,length=1.0,count=1
這裡是二號位置!hight=1.0,length=1.0,count=1
這裡是三號位置!hight=1.0,length=1.0,count=1
我們來看看這種方式有什麼好處?
假如我們需要新增乙個需要展示資料的地方,直接讓這個地方實現observer介面,然後註冊主題就好了,不需要修改任何源**
如果不想訂閱了呢?這就更簡單了,直接呼叫主題的remove方法就行了
我們把思維發散一點,假設這是乙個大型架構的部分實現,假設subject是註冊中心,observer是客戶端,這種實現方式其實就不能滿足我們的需求了,我們來看以下情景:
假如客戶端宕機了,然後重啟之後,註冊中心遲遲沒有更新資料,那麼客戶端豈不是一直沒有資料?這就很尷尬,所以除了客戶端推送的方式之外,還應該有乙個自己拉資料的辦法
我們來改進一下**
修改subject
public
inte***ce subject
修改datasource
public
class
datasource
implements
subject
public
void
registobserver(observer observer)
}public
void
removeobserver(observer observer)
}public
void
notifyobservers()
}public
void
changed()
public
void
setdata(float high, float length, int count)
}
修改observer
public
inte***ce observer
修改place1
public
class
place1
implements
observer,displaydata
public
void
display()
public
void
updata(float high, float length, int count)
//增加拉的方法
public
void
pull()
}
我們來測試一下
public
static
void
main(string args)
執行結果如下:
這裡是一號位置!hight=0.0,length=0.0,count=0
這就實現了客戶端自己拉資料,當然我們可以把功能實現得更複雜,比如說針對不同的訂閱物件傳送不同的資料,觀察者去拉自己想要的資料等等,有興趣的朋友可以自己去嘗試實現一下,我在這裡就不贅述了。
ps:原始碼位址
python觀察者模式 python 觀察者模式
python 觀察者模式 前言e 寫的倉促就不截uml類圖了,書本chapter10,p313能看到圖 一旦觀察的主題有更新,就會通知到觀察者們,下面的例子是最簡單的乙個觀察者範例,假設這是一群投機分子密切關注 軍 火 倉庫的產品與數量變動 class inventory def init self...
觀察者模式
觀察者模式 observer 完美的將觀察者和被觀察的物件分離開。舉個例子,使用者介面可以作為乙個觀察者,業務資料是被觀察者,使用者介面觀察業務資料的變化,發現資料變化後,就顯示在介面上。物件導向設計的乙個原則是 系統中的每個類將重點放在某乙個功能上,而不是其他方面。乙個物件只做一件事情,並且將他做...
觀察者模式
觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某乙個主題物件。這個主題物件在狀態上發生變化時,會通知所有觀察者物件,讓他們能夠自動更新自己 任何乙個模式都是離不開角色的,這裡也會有幾種角色 抽象主題角色 把所有對觀察者物件的引用儲存在乙個集合中,每個抽象主題角色都可以有任意數量的觀察...