暗中等待:觀察者模式解析

設計模式想必大家都懂一些,不僅能體現平時設計寫代碼的基本功,而且也是面試時的高頻考點。今天來講解學習下 觀察者模式。 本文在講解具體模式的同時,也會列舉 jdk 以及 常用框架中使用到的地方,幫助大家加深理解。

設計模式的學習,我的建議是,首先弄懂它的含義,和前人已經總結沉澱下來的設計原則。將這些概念記在心裏,當工作中碰見對應的需求開發工作時,按照原則去認真思考、設計實現,最終符合要求的結果往往就已經是一些設計模式的具體實現了。

場景舉例

首先列出一個實戰場景,用這個場景來講述觀察者模式是什麼,以及爲什麼適用這個場景。

現在有一個氣象觀測站應用系統,主要包含三個部分,獲取氣象數據的物理裝置(包括溫度、溼度、密度等)、WeatherData(追蹤氣象站的數據並更新佈告板)和佈告板(顯示看板給用戶看)。

首先來看一個錯誤示例:

public class WeatherData {
    // 實例變量聲明

    // 氣象數據變化時更新對應的佈告板
    public void measurementsChanged() {
        float temp = getTemperature();
        float humidity = getHumidity();
        float pressure = getPressure();
        // 更新各種佈告板
        currentConditionDisplay.update(temp,humidity,pressure);
        statsticConditionDisplay.update(temp,humidity,pressure);
    }
}

首先各種佈告板應該是一個統一的接口,其次更新佈告板不能針對具體實現編程,這樣會導致以後在增加或者刪除佈告板時必須修改程序。

結合設計原則思考

根據這個場景我們首先按照設計原則來思考:

  • 找出程序中變化的方面,然後將其和固定的部分分離。

場景中氣象站觀測的天氣數據時變化的,佈告板的數量和類型是變化的。

  • 針對接口編程,不針對實現編程。

這裏主要指我們的佈告板應該是一個接口,而天氣對象 WeatherData 也應該是一個統一接口,後面還會介紹。

  • 多用組合,少用繼承

這裏佈告板和天氣對象之間的關係應該爲天氣對象組合佈告板,這種關係不是通過繼承來的,而是通過在運行時通過組合的方式產生的。

這個場景,我們能看到,只要天氣對象有數據變更,就需要通知所有佈告板,這是一個典型的主題-訂閱模式,也就是我們今天要學習的觀察者模式。

我們把 WeatherDta 對象當作主題,把佈告板當做觀察者,佈告板爲了獲取信息,必須向 WeatherData 對象註冊。

每個佈告板都有差異,這也就是我們爲什麼需要一個共同的接口。儘管佈告板的類不一樣,但是它們應該實現相同的接口,好讓 WeatherData 對象能夠知道如何把觀測值傳給他們。

大師的設計

首先定義對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會收到通知並自動更新。正好對應我們舉例中的 WeatherData 主題對象,當它改變時,所有的佈告板收到狀態變更通知,進行各自業務處理。

類圖如下:

通過上面觀察者模式的類圖,我們可以看到兩個對象之間是松耦合的,但他們之間依然可以交互,但是不太清楚彼此的細節。 觀察者模式提供了這種對象設計,讓主題和觀察者之間松耦合。

你可能要問爲什麼呢?

關於觀察者的一切,主題只知道觀察者實現了某個接口(即 Observer 接口)。主題不需要知道觀察者的具體類是誰,做了些什麼以及任何細節。

任何時候我們都可以增加新的觀察者。因爲主題唯一依賴的東西是一個實現 Observer 接口的對象列表,所以可以隨時增加觀察者。

當有新類型觀察者出現時,主題的代碼不需要作任何修改。我們要做的就是在新的類裏實現觀察者接口,然後註冊爲觀察者即可。主題不在乎別的,它只會發送通知給所有實現了觀察者接口的註冊對象。

改變主題或者觀察者其中一方,並不會影響另一方。因爲兩者是松耦合的,所以只要他們之間的接口仍被遵守,我們就可以自由的改變他們。

所以這就總結出我們今天新學習的設計原則:

爲了交互對象之間的松耦合設計而努力。

實際應用

  1. java中內置的觀察者模式,java.util包內包含基本的Observer接口與Observable類,可以使用推(push)或拉(pull)的方式傳數據。

  2. jdk 中 JavaBeans 裏的觀察者模式,具體查看 PropertyChangeListener 接口。

  3. 想一下我們平時用的消息隊列,比如rocketMQ等,本質上也是運用了觀察者模式的思想;

總結

觀察者模式:在對象之間定義一對多的依賴,這樣一來,當一個對象改變狀態,依賴它的對象都會收到通知,並自動更新。

後面一篇內容,將會帶來裝飾着模式的講解,敬請期待。

原創真心不易,希望你能幫我個小忙唄,如果本文內容你覺得有所收穫,請幫忙點個“在看”唄,或者轉發分享讓更多的小夥伴看到。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章