觀察者模式(Observer Pattern)
目標
物件之間一對多的依賴關係,當物件狀態改變時,所有依賴者會被通知
架構
Subject
:主題- 特定事件發生時,會通知觀察者
- 如資料改變
- 新增/移除觀察者:
Attach(Observer), Detach(Observer)
- 用
Notify(data)
通知觀察者主題有更新
- 特定事件發生時,會通知觀察者
Observer
:觀察者- 訂閱主題,以便在更新時收到通知
- 觀察者收到通知時呼叫
Update(Subject)
以處理事件
分析
設計守則:盡量讓需要互動的物件的關係鬆綁
- 主題和觀察者鬆綁
- 主題不用知道觀察者的具體類別,只知道觀察者有實作特定介面(
Observer
) - 可以加入/移除新的觀察者,且主題的程式碼不需修改
- 主題不用知道觀察者的具體類別,只知道觀察者有實作特定介面(
實作
有一觀測工作站數據的物件,在數據異常時可以通知到多個平台(Email, 簡訊, App),
且使用者可以自由調整各平台的通知設定。
- 觀察者之間彼此獨立,不可依頼通知觀察者的順序
- 主題可以控制改變的定義(如溫度變化超過1度)
- Push model/Pull model
- Push model
- 推送所有資料給Observer
- Subject要知道Observer需要什麼,彈性較差
- Observer會接收到不必要的資料
- Pull model
- 提供必要的資料或其來源(如data id或Subject本身)給Observer,由Observer自行取得相關資料
- 每個Observer都要重新取得資料,效率較差
- Push model
- C#的實作:委託,可看作對函數的抽象,是函數的類別
- 委託物件所搭載的方法並不需要屬於同一個類別(即不需要Observer介面)
- 可以實作一個Subject管理員
用途
當一個物件的改變需要同時改變其他物件時
- 訂閱服務
- MVC架構:後端資料更新、前端顯示資料
- UI事件:OnClick, OnHover
- 觸發事件
其他
- 目前的社群網站則是訂閱後仍會篩選並提供部份資料,而RSS訂閱後可取得所有資料的更新
參考
- Wiki
- Head-First Design Pattern
- 大話設計模式
- 設計模式與遊戲開發的完美結合
- https://notfalse.net/10/observer-pattern