在 Java8 環境下實現觀察者模式的實例分析
大小:0.5 MB 人氣: 2017-10-12 需要積分:1
標簽:JAVA(102450)
觀察者(Observer)模式又名發布-訂閱(Publish/Subscribe)模式,是四人組(GoF,即 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides)在1994合著的《設計模式:可復用面向對象軟件的基礎》中提出的(詳見書中293-313頁)。盡管這種模式已經有相當長的歷史,它仍然廣泛適用于各種場景,甚至成為了標準Java庫的一個組成部分。目前雖然已經有大量關于觀察者模式的文章,但它們都專注于在 Java 中的實現,卻忽視了開發者在Java中使用觀察者模式時遇到的各種問題。本文的寫作初衷就是為了填補這一空白:本文主要介紹通過使用 Java8 架構實現觀察者模式,并在此基礎上進一步探討關于經典模式的復雜問題,包括匿名內部類、lambda 表達式、線程安全以及非平凡耗時長的觀察者實現。本文內容雖然并不全面,很多這種模式所涉及的復雜問題,遠不是一篇文章就能說清的。但是讀完本文,讀者能了解什么是觀察者模式,它在Java中的通用性以及如何處理在 Java 中實現觀察者模式時的一些常見問題。
觀察者模式
根據 GoF 提出的經典定義,觀察者模式的主旨是:
定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。
什么意思呢?很多軟件應用中,對象之間的狀態都是互相依賴的。例如,如果一個應用專注于數值數據加工,這個數據也許會通過圖形用戶界面(GUI)的表格或圖表來展現或者兩者同時使用,也就是說,當底層數據更新時,相應的 GUI 組件也要更新。問題的關鍵在于如何做到底層數據更新時 GUI 組件也隨之更新,同時盡量減小 GUI 組件和底層數據的耦合度。
一種簡單且不可擴展的解決方案是給管理這些底層數據的對象該表格和圖像 GUI 組件的引用,使得對象可以在底層數據變化時能夠通知 GUI 組件。顯然,對于處理有更多 GUI 組件的復雜應用,這個簡單的解決方案很快顯示出其不足。例如,有20個 GUI 組件都依賴于底層數據,那么管理底層數據的對象就需要維護指向這20個組件的引用。隨著依賴于相關數據的對象數量的增加,數據管理和對象之間的耦合度也變得難以控制。
另一個更好的解決方案是允許對象注冊獲取感興趣數據更新的權限,當數據變化時,數據管理器就會通知這些對象。通俗地說就是,讓感興趣的數據對象告訴管理器:“當數據變化時請通知我”。此外,這些對象不僅可以注冊獲取更新通知,也可以取消注冊,保證數據管理器在數據變化時不再通知該對象。在 GoF 的原始定義中,注冊獲取更新的對象叫作“觀察者”(observer),對應的數據管理器叫作“目標”(Subject),觀察者感興趣的數據叫作“目標狀態”,注冊過程叫“添加”(attach),撤銷觀察的過程叫“移除”(detach)。前文已經提到觀察者模式又叫發布-訂閱模式,可以理解為客戶訂閱關于目標的觀察者,當目標狀態更新時,目標把這些更新發布給訂閱者(這種設計模式擴展為通用架構,稱為發布——訂閱架構)。這些概念可以用下面的類圖表示:
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%