觀察者模式

2021-08-15 18:32:26 字數 3254 閱讀 3353

和以前一樣,在介紹觀察者模式之前,我們先看看如果不用觀察者模式會是怎樣的

首先我們假定以下情景:有乙個資料來源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 完美的將觀察者和被觀察的物件分離開。舉個例子,使用者介面可以作為乙個觀察者,業務資料是被觀察者,使用者介面觀察業務資料的變化,發現資料變化後,就顯示在介面上。物件導向設計的乙個原則是 系統中的每個類將重點放在某乙個功能上,而不是其他方面。乙個物件只做一件事情,並且將他做...

觀察者模式

觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某乙個主題物件。這個主題物件在狀態上發生變化時,會通知所有觀察者物件,讓他們能夠自動更新自己 任何乙個模式都是離不開角色的,這裡也會有幾種角色 抽象主題角色 把所有對觀察者物件的引用儲存在乙個集合中,每個抽象主題角色都可以有任意數量的觀察...