還記得警匪片上,匪徒們是怎麼配合實施犯罪的嗎?乙個團夥在進行盜竊的時候,總有一兩個人在門口把風——如果有什麼風吹草動,則會立即通知裡面的同夥緊急撤退。也許放風的人並不一定認識裡面的每乙個同夥;而在裡面也許有新來的小弟不認識這個放風的。但是這沒什麼,這個影響不了他們之間的通訊,因為他們之間有早已商定好的暗號。呵呵,上面提到的放風者、偷竊者之間的關係就是觀察者模式在現實中的活生生的例子。
觀察者(observer)模式又名發布-訂閱(publish/subscribe)模式。gof 給觀察者模式如下定義:定義物件間的一種一對多的依賴關係,當乙個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。
在這裡先講一下物件導向設計的乙個重要原則——單一職責原則。系統的每個物件應該將重點放在問題域中的離散抽象上。因此理想的情況下,乙個物件只做一件事情。這樣在開發中也就帶來了諸多的好處:提供了重用性和維護性,也是進行重構的良好的基礎。
因此幾乎所有的設計模式都是基於這個基本的設計原則來的。觀察者模式的起源我覺得應該是在gui 和業務資料的處理上,因為現在絕大多數講解觀察者模式的例子都是這一題材。但是觀察者模式的應用決不僅限於此一方面。
下面我們就來看看觀察者模式的組成部分。
1) 抽象目標角色(subject):目標角色知道它的觀察者,可以有任意多個觀察者觀察同乙個目標。並且提供註冊和刪除觀察者物件的介面。目標角色往往由抽象類或者介面來實現。
2) 抽象觀察者角色(observer):為那些在目標發生改變時需要獲得通知的物件定義乙個更新介面。抽象觀察者角色主要由抽象類或者介面來實現。
3) 具體目標角色(concrete subject):將有關狀態存入各個concrete observer 物件。當它的狀態發生改變時, 向它的各個觀察者發出通知。
4) 具體觀察者角色(concrete observer):儲存有關狀態,這些狀態應與目標的狀態保持一致。實現observer 的更新介面以使自身狀態與目標的狀態保持一致。在本角色內也可以維護乙個指向concrete subject 物件的引用。
放上觀察者模式的類圖,這樣能將關係清晰的表達出來。
下面是乙個獵頭的典型例子。這個圖中有2個角色-獵頭和求職者。求職者先在獵頭處註冊,當有新的工作機會時獵頭就會通知求職者。
//抽象目標角色--subject
public
inte***ce
subject
//具體目標角色--concrete subject
public
class
headhunter
implements
subject
@override
public
void
registerobserver(observer o)
@override
public
void
removeobserver(observer o)
@override
public
void
notifyallobservers()
}public
void
addjob(string job)
public arraylistgetjobs()
public string tostring()
}//抽象觀察者角色--observer
public
inte***ce
observer
//具體觀察者角色--concrete observer
public
class
jobseeker
implements
observer
@override
public
void
update(subject s)
}//客戶端測試
public
class
testclient
}
驗證輸出
mike
gotnotified!
[google job]
chris
gotnotified!
[google job]
jeff
gotnotified!
[google job]
mike
gotnotified!
[google job, yahoo job]
chris
gotnotified!
[google job, yahoo job]
jeff
gotnotified!
[google job, yahoo job]
觀察者模式在關於目標角色、觀察者角色通訊的具體實現中,有兩個版本。一種情況便是目標角色在發生變化後,僅僅告訴觀察者角色「我變化了」;觀察者角色如果想要知道具體的變化細節,則就要自己從目標角色的介面中得到。這種模式被很形象的稱為:拉模式——就是說變化的資訊是觀察者角色主動從目標角色中「拉」出來的。
還有一種方法,那就是我目標角色「服務一條龍」,通知你發生變化的同時,通過乙個引數將變化的細節傳遞到觀察者角色中去。這就是「推模式」——管你要不要,先給你啦。
這兩種模式的使用,取決於系統設計時的需要。如果目標角色比較複雜,並且觀察者角色進行更新時必須得到一些具體變化的資訊,則「推模式」比較合適。如果目標角色比較簡單,則「拉模式」就很合適啦。
設計模式總結篇系列 觀察者模式(Observer)
觀察者模式中通常有兩個基本的概念主題 觀察者和被觀察者。當被觀察者狀態發生改變時,需要通知相應的觀察者,當然,每個被觀察者所對應的觀察者可能不知乙個,他們之間是1 n的關係。用專業一點的術語對觀察者模式的描述為 當乙個物件變化時,其它依賴該物件的物件都會收到通知,並且隨著變化。觀察者模式的一般實現方...
python 設計模式 觀察者 觀察者設計模式
在觀察者設計模式這種模式中,物件被表示為等待事件觸發的觀察者。一旦發生指定的事件,觀察者就會關注該主體。當事件發生時,主體告訴觀察者它已經發生。以下uml圖表示觀察者模式 如何實現觀察者模式?現在讓我們來看看如何實現觀察者模式。參考以下實現 import threading import time ...
設計模式 觀察者模式
觀察者模式定義了物件間一對多的依賴關係,乙個物件發生變化時,所有依賴它的物件都得到通知並被自動更新。本文主要闡述觀察者模式在分布式scada人機介面中的使用,利用這種模式使得人機介面顯示效率更高。發布者 郵局 觀察者 參與者 讀者 訂閱者 當郵局收到報社新雜誌的時候,即郵局狀態發生了改變,於是郵局把...