觀察者模式(Observer Pattern)

目標

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

有一觀測工作站數據的物件,在數據異常時可以通知到多個平台(email, 簡訊, app)
且使用者可以自由調整各平台的通知設定

架構

  • Subject: 主題
    • 當資料改變,就會通知觀察者
    • 新增/移除觀察者: Attach(Observer), Detach(Observer)
    • 通知觀察者主題有更新: Notify(data)
  • Observer: 觀察者
    • 訂閱主題,以便在更新時收到通知
    • 觀察者收到通知: Update(Subject)

      分析

設計守則:盡量讓需要互動的物件的關係鬆綁

  • 主題和觀察者鬆綁
    • 主題只知道觀察者有實作特定介面(Observer),不用知道觀察者的具體類別
    • 任何時候都可以加入新的觀察者,且主題的程式碼不需修改

實作

  • 觀察者之間彼此獨立,不可依頼通知觀察者的順序
  • 主題可以控制改變的定義(如溫度變化超過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