觀察者模式(Observer Pattern)

目標

物件之間一對多的依賴關係,當物件狀態改變時,所有依賴者會被通知

架構

From Wiki

  • 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都要重新取得資料,效率較差
  • C#的實作:委託,可看作對函數的抽象,是函數的類別
    • 委託物件所搭載的方法並不需要屬於同一個類別(即不需要Observer介面)
  • 可以實作一個Subject管理員

用途

當一個物件的改變需要同時改變其他物件時

  • 訂閱服務
  • MVC架構:後端資料更新、前端顯示資料
  • UI事件:OnClick, OnHover
  • 觸發事件

其他

  • 目前的社群網站則是訂閱後仍會篩選並提供部份資料,而RSS訂閱後可取得所有資料的更新

參考

  • Wiki
  • Head-First Design Pattern
  • 大話設計模式
  • 設計模式與遊戲開發的完美結合
  • https://notfalse.net/10/observer-pattern