掌握設計模式--觀察者模式

渊渟岳發表於2025-01-17

觀察者模式(Observer Pattern)

觀察者模式(Observer Pattern)是一種行為設計模式,它定義了物件間的一對多依賴關係,使得當一個物件狀態發生改變時,所有依賴於它的物件都會自動收到通知並更新。

主要組成部分

主題(Subject):主題是被觀察的物件,它維護一個觀察者列表。當它的狀態發生改變時,會通知所有的觀察者。主題提供方法來註冊、登出觀察者。

觀察者(Observer):觀察者是依賴於主題的物件,它會在主題狀態發生變化時收到通知,進而更新自身的狀態。觀察者有一個更新方法,當主題狀態變化時,主題會呼叫此方法來通知觀察者。

工作流程

  1. 註冊觀察者:觀察者透過主題提供的註冊方法將自己註冊到主題上。
  2. 狀態變化:主題的狀態發生變化時,它會遍歷其所有註冊的觀察者。
  3. 通知觀察者:主題呼叫每個觀察者的更新方法,通知它們進行狀態更新。
  4. 更新觀察者:觀察者根據通知更新自己的狀態,通常會重新渲染介面或進行其他的狀態更新。

案例實現

假設有一個溫度監控系統:

  • 主題:溫度感測器,當溫度發生變化時,它會通知所有依賴於它的觀察者。
  • 觀察者:可以是不同的顯示裝置或報警系統,溫度變化時,它們會根據新溫度執行相應操作。

案例類圖

image

觀察者介面

用於觀察溫度變化的介面,訂閱的主題發生變化時,透過觀察者介面的update方法來通知訂閱了的所有觀察者。

interface Observer {
    void update(int temperature);
}

觀察者實現類

// 觀察者實現類1
class DisplayDevice implements Observer {
    @Override
    public void update(int temperature) {
        System.out.println("顯示裝置:溫度更新到" + temperature);
    }
}

// 觀察者實現類2
class AlarmSystem implements Observer {
    @Override
    public void update(int temperature) {
        if (temperature > 42) {
            System.out.println("警報:溫度超過閾值!");
        }
    }
}

主題類(被觀察者)

class TemperatureSensor {
    // 觀察者列表
    private List<Observer> observers = new ArrayList<>();
    private int temperature;

    // 註冊觀察者
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    // 移除觀察者
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    // 設定溫度並通知觀察者
    public void setTemperature(int temperature) {
        this.temperature = temperature;
        notifyObservers();
    }

    // 通知所有觀察者
    private void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(temperature);
        }
    }
}

測試客戶端

public class ObserverPatternDemo {
    public static void main(String[] args) {
        // 建立主題和觀察者
        TemperatureSensor sensor = new TemperatureSensor();
        Observer display = new DisplayDevice();
        Observer alarm = new AlarmSystem();

        // 註冊觀察者:如果沒註冊,那就不會通知
        sensor.addObserver(display);
        sensor.addObserver(alarm);

        // 改變主題的狀態
        sensor.setTemperature(45);
        sensor.setTemperature(28);
    }
}

測試輸出結果

顯示裝置:溫度更新到45

警報:溫度超過閾值!

顯示裝置:溫度更新到28

優缺點和使用場景

優點

  1. 松耦合:觀察者與主題之間是松耦合的,主題不需要知道具體的觀察者,觀察者也不需要了解主題的內部實現。
  2. 動態新增或刪除觀察者:可以在執行時動態地新增或刪除觀察者。

缺點

  1. 多次更新:如果有大量觀察者,狀態變化可能導致多次呼叫更新方法,效能可能受到影響。
  2. 迴圈依賴:觀察者之間如果互相通知更新,可能引起迴圈依賴或無限迴圈。

觀察者模式是處理事件驅動系統或需要多個物件同步更新狀態的常用模式,尤其在分散式系統、GUI框架中應用廣泛。

適用場景

  • 事件驅動的系統:例如GUI框架(按鈕點選、介面更新等)、訊息通知系統等。
  • 釋出-訂閱系統:如訊息佇列系統、新聞訂閱、社交媒體更新等。
  • 資料同步:多個模組需要同步更新某些共享資料時,如溫度監控、股票價格變化等。

觀察者模式的應用

Spring的事件機制ApplicationEvent是事件物件,ApplicationListener是事件監聽器,當ApplicationEvent釋出時,所有註冊了該事件型別的ApplicationListener會被通知並處理該事件。ApplicationEventPublisher介面(通常是ApplicationContext的實現類)作為被觀察者,ApplicationListener作為觀察者。事件的釋出和監聽實現了松耦合的通知機制。

Java Web中的監聽器,它透過監聽和響應Web應用的生命週期事件、HTTP會話事件、請求事件以及屬性變化事件。常見的監聽器介面包括ServletContextListenerHttpSessionListenerServletRequestListener等,實現相應的監聽介面,即可完成相應事件的監聽。監聽器機制的使用可以幫助開發者在特定事件發生時執行一些處理邏輯,保證程式碼的解耦和靈活性。

總結

觀察者模式是一種行為設計模式,其核心在於透過定義一對多的依賴關係,使得當被觀察者的狀態發生變化時,所有依賴的觀察者自動收到通知並更新,從而實現物件之間的松耦合和動態響應,同時便於觀察者的擴充套件。

image

需要檢視往期設計模式文章的,可以在個人主頁中或者文章開頭的集合中檢視,可關注我,持續更新中。。。


超實用的SpringAOP實戰之日誌記錄

2023年下半年軟考考試重磅訊息

透過軟考後卻領取不到實體證書?

計算機演算法設計與分析(第5版)

Java全棧學習路線、學習資源和麵試題一條龍

軟考證書=職稱證書?

軟考中級--軟體設計師毫無保留的備考分享

相關文章