首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

觀察者模式深度解析:從經典定義到 Java 實戰

     編輯:Java 程式設計入門

模式定義

觀察者模式又稱「發布-訂閱」,定義物件間一對多依賴:當主題狀態改變,自動通知所有觀察者。核心在於解耦主題與觀察者,支援動態訂閱/取消訂閱。

四大角色

角色說明對應類別
Subject (抽象主題)管理觀察者集合,提供註冊/移除/通知介面Watched 介面
Observer (抽象觀察者)定義更新介面Watcher 介面
ConcreteSubject (具體主題)實作主題邏輯,狀態變更時通知ConcreteWatched
ConcreteObserver (具體觀察者)實作更新邏輯,同步主題狀態ConcreteWatcher

核心流程

  1. 觀察者呼叫 registerObserver() 將自己加入主題列表。
  2. 主題狀態改變,呼叫 notifyObservers()。
  3. 主題遍歷列表,呼叫每個觀察者的 update()。
  4. 觀察者可呼叫 removeObserver() 取消訂閱。

Java 完整實作

// 1. 抽象主題
interface Watched {
    void registerSubscriber(Watcher watcher);
    void removeSubscriber(Watcher watcher);
    void sendNews();
}

// 2. 抽象觀察者
interface Watcher {
    void updateNews();
}

// 3. 具體主題
class ConcreteWatched implements Watched {
    private final List subscribers = new ArrayList<>();

    @Override public void registerSubscriber(Watcher w) { subscribers.add(w); }
    @Override public void removeSubscriber(Watcher w) { subscribers.remove(w); }

    @Override public void sendNews() {
        System.out.println("開始推送新聞...");
        for (Watcher w : subscribers) w.updateNews();
        System.out.println("推送結束。");
    }
}

// 4. 具體觀察者
class ConcreteWatcher implements Watcher {
    private final String name;
    public ConcreteWatcher(String name) { this.name = name; }
    @Override public void updateNews() { System.out.println(name + " 收到最新新聞!"); }
}

// 5. 測試
public class ObserverDemo {
    public static void main(String[] args) {
        ConcreteWatched news = new ConcreteWatched();
        news.registerSubscriber(new ConcreteWatcher("讀者A"));
        news.registerSubscriber(new ConcreteWatcher("讀者B"));
        news.registerSubscriber(new ConcreteWatcher("讀者C"));
        news.sendNews();
        System.out.println("--- 讀者A 取消訂閱 ---");
        news.removeSubscriber(new ConcreteWatcher("讀者A")); // 注意:需保留引用才能移除
        news.sendNews();
    }
}

關鍵改進點

  • 保留觀察者引用:測試中 new ConcreteWatcher("讀者A") 建立新物件無法移除,實務應保留變數或用 ID 對應。
  • 執行緒安全:多執行緒環境下,subscribers 應用 CopyOnWriteArrayList 或同步鎖。
  • 異步通知:耗時觀察者可用 ExecutorService 非阻塞通知。
  • 弱引用:防止觀察者記憶體洩漏,可用 WeakReference<Watcher>。

JDK 內建支援

  • java.util.Observable / Observer(Java 9 棄用,因設計缺陷)。
  • 推薦:自行實作或使用 PropertyChangeListener、EventListener、Guava EventBus、Spring ApplicationEventPublisher、RxJava Observable 等成熟事件總線。

應用場景

  • GUI 事件處理(按鈕點擊、滑鼠移動)。
  • 模型-視圖同步(MVC/MVVM)。
  • 訊息推送、日誌記錄、快取失效通知。
  • 微服務事件驅動架構(領域事件)。

總結

觀察者模式是「鬆耦合、高擴展」的經典範例。掌握其核心結構、避開常見坑點(引用管理、執行緒安全、異步處理),並善用成熟框架而非重造輪子,是架構師的必修功課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved