觀察者模式

2021-07-17 00:13:06 字數 2507 閱讀 6989

我們知道物件導向的乙個主題就是類例項的實體化,即每個實體都有自己的狀態和行為,而仿照真實世界的不同客觀實體之間是存在諸多聯絡的,則乙個很常見的物件聯動方式就是反饋行為的發生。最常見的場景如:班車進站,眾旅客上車,這是乙個典型的物件反饋行為。由此產生的一種描述該現象的設計模式,稱之為觀察者模式,也有其他的名字如發布-訂閱模式、模型-檢視模式等。

觀察者模式作為一種物件行為型模式,用於監控物件狀態,並根據物件狀態的改變而通知與其存在依賴關係的其他物件,所謂的「通知」其實就是產生反饋效果,所以該模式通常應用於一對一和一對多的物件關係中。

以上面提到的班車進站和乘客上車為例,結構如下:

1、observer作為觀察者介面,只有乙個update方法,作為抽象的響應函式,重點是其引數

2、passenger作為具體觀察者,即等待車輛的乘客,實現update函式,即上車動作,這裡的引數是觀察目標,即車輛的編號(標誌車輛)

3、observable作為觀察目標類,包含乙個對觀察者的集合,以實現在自身狀態發生改變時,完成「通知」功能

4、bus繼承observable類,也就是具體的目標類,這裡模仿的是汽車進站場景,所以自身提供了乙個進站函式(覆蓋空的父類change函式),如果是汽車的其他場景,則需要提供其他型別的函式,作為改變狀態,產生反饋源資訊的條件。

示例**

public class t

}inte***ce observer

class passenger implements observer

public void update(string id)

}class observable

public void add(observer o)

public void delete(observer o)

public void notify()

觀察目標類

public class observable 

/* 在新增觀察者的函式中可以看出,即便vector作為所謂的執行緒安全集合

自帶的同步機制也只是實現addelement方法是同步方法,並不能保證addobserver的同步

所以addobserver操作仍然需要synchronized修飾

在去除重複觀察者方面,利用vector的contains方法,而不是set集合,原因猜測

1.對觀察者模式的支援提出的時間比較早,跟vector一樣古老,所以用的是vector,

至於沒有更改估計跟vector一直用enumeration至死都沒有改用iterator一樣,

太古老,所以直接放棄不用了。沒有考證,只是猜測

2.執行緒安全集合,雖然此處沒看出在同步方法之上再覆蓋一層同步方法有何益處(

除otifyobservers之外,所有方法都是synchronized修飾的同步方法,且notifyobservers

函式中是複製出新集合,vector陣列是私有屬性,而且整個類中的所有方法都不存在逃逸情況)

*/public synchronized void addobserver(observer o)

}public synchronized void deleteobserver(observer o)

/* 如果只需要傳遞觀察目標介面,則第二個引數為null

甚至專門提供了乙個無參的notifyobservers方法來實現

*/public void notifyobservers()

public void notifyobservers(object arg)

for (int i = arrlocal.length-1; i>=0; i--)

((observer)arrlocal[i]).update(this, arg);

}public synchronized void deleteobservers()

protected synchronized void setchanged()

protected synchronized void clearchanged()

public synchronized boolean haschanged()

public synchronized int countobservers()

}

觀察者模式適用於物件的狀態更新會產生對其他物件的影響,即需要其他物件針對該物件的更新操作作出自己的更新/調整操作。較好的類之間的耦合情況應該是,乙個類例項的更新只對乙個或很少的其他例項產生影響。

參考設計模式開閉原則,關於update函式的引數問題,如果無引數則具體目標類與具體觀察者類無依賴關係,只是針對抽象類程式設計,滿足開閉原則;如果需要以具體目標類作為引數,則如果需要的狀態為抽象目標類的共有狀態,則仍可以滿足開閉原則,面向抽象程式設計,如果需要提供的目標類狀態資訊為具體目標類私有,則此時觀察者類面向具體目標類程式設計,違反開閉原則,此種情形下抽象目標類的作用僅限於復用,不提供抽象程式設計的幫助。

python觀察者模式 python 觀察者模式

python 觀察者模式 前言e 寫的倉促就不截uml類圖了,書本chapter10,p313能看到圖 一旦觀察的主題有更新,就會通知到觀察者們,下面的例子是最簡單的乙個觀察者範例,假設這是一群投機分子密切關注 軍 火 倉庫的產品與數量變動 class inventory def init self...

觀察者模式

觀察者模式 observer 完美的將觀察者和被觀察的物件分離開。舉個例子,使用者介面可以作為乙個觀察者,業務資料是被觀察者,使用者介面觀察業務資料的變化,發現資料變化後,就顯示在介面上。物件導向設計的乙個原則是 系統中的每個類將重點放在某乙個功能上,而不是其他方面。乙個物件只做一件事情,並且將他做...

觀察者模式

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