03.05 設計模式之觀察者模式

觀察者模式定義

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

定義對象間 1:N 的依賴關係,當對象狀態變化時,它的所有依賴對象都能被自動通知和更新。

面向對象設計將系統劃分為一系列的互相協作的對象,問題是如何維護這些相關對象間的一致性。為了避免這些對象的複用性,不希望通過對象間的緊耦合來實現一致性。

觀察者模式描述了這種對象間的依賴關係,涉及了兩個頂層抽象,即觀察者和主題。主題可以被任意多的觀察者訂閱,當主題狀態發生變化時,訂閱該主題的觀察者都會被自動通知。相應的,觀察者可以查詢主題以同步主題狀態。

觀察者模式的類圖

設計模式之觀察者模式

抽象主題:Subject

  • 感知所有的觀察者,一個主題可以被任意數量的觀察者訂閱
  • 提供綁定和解綁觀察者實例的接口

抽象觀察者:Observer

  • 定義更新接口以便主題發生變更時進行通知

具體主題:ConcreteSubject

  • 存儲觀察者對象所感興趣的狀態信息
  • 當主題的狀態變化時給所有的觀察者發送通知

具體觀察者:ConcreteObserver

  • 持有具體主題的實例引用
  • 存儲需要與主題保持一致的狀態信息
  • 實現Observer的更新接口以保持它的狀態與主題保持一致

觀察者模式的時序如下圖所示,存在兩個維度的交互:

  • 主題發生變更,將推送變更到觀察者
  • 觀察者查詢主題變更,同步狀態信息
設計模式之觀察者模式

觀察者模式的優點

觀察者和主題之間的松耦合

  • 對於主題而言,它只感知到自身持有的觀察者列表,而且是對抽象觀察者的依賴,主題並知道具體觀察者對象是什麼,由此實現的主題和觀察者之間的依賴關係是基於抽象的且最小化的。

易於擴展:支持開閉原則

支持廣播

  • 主題持有觀察者列表,主題狀態發生變更時不需要明確具體的接收者,直接通過廣播形式進行通知到觀察者列表

觀察者模式的缺點

  • 如果主題的觀察者數量過多,則狀態通知可能會存在性能問題
  • 觀察者和觀察目標之間有循環依賴的則會觸發循環調用
  • 觀察者僅僅知道主題發生了變化,無法感知主題對象是如何進行變化

觀察者模式符合的OOP原則

開閉原則

主題接口僅僅依賴於觀察者接口,具體主題的類也僅僅是依賴於觀察者接口,如果增加新的實現觀察者接口的類,不必修改創建具體主題的類的代碼。同樣,創建具體觀察者的類僅僅依賴於主題接口,如果增加新的實現主題接口的類,也不必修改創建具體觀察者類的代碼。

里氏替換原則

抽象了主題和觀察者,通過實現抽象接口定義具體主題類和具體觀察者類。面向接口編程,符合里氏替換原則。

觀察者模式的適用場景

  • 當你設計的抽象具有兩個方面,一個抽象依賴於另一個,將他們封裝到不同對象中有助於降低耦合和提高複用性。
  • 某個對象數據更新需要通知其他對象,但又期望避免當前對象與被通知對象的緊耦合
  • 某個對象數據更新,需要讓其他對象也自動更新自身狀態,當前對象不需要知道具體有多少對象需要更新。


分享到:


相關文章: