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

Java 觀察者模式完整實戰:從核心角色到代碼落地

     編輯:Java 相關知識

前言

觀察者模式定義對象間一對多依賴:主題狀態變更時,自動通知所有觀察者。廣泛應用於事件總線、GUI 監聽、消息推送、Spring ApplicationEvent 等場景。

核心角色(四大接口/類)

角色職責典型實現
抽象主題管理觀察者集合,提供註冊/移除/通知接口接口 Watched
抽象觀察者定義更新接口接口 Watcher
具體主題狀態變更時調用通知,攜帶業務數據類 ConcreteWatched
具體觀察者實現更新邏輯,同步主題狀態類 ConcreteWatcher

代碼實現(標準 JDK,無第三方依賴)

1. 抽象觀察者

public interface Watcher {
    void update(String event);  // 也可傳遞 EventObject 豐富載荷
}

2. 抽象主題

public interface Watched {
    void addWatcher(Watcher watcher);
    void removeWatcher(Watcher watcher);
    void notifyWatchers(String event);
}

3. 具體觀察者

public class ConcreteWatcher implements Watcher {
    @Override
    public void update(String event) {
        System.out.println("收到通知: " + event);
        // 實際業務:刷新 UI、發送郵件、寫日誌...
    }
}

4. 具體主題

import java.util.*;

public class ConcreteWatched implements Watched {
    private final List<Watcher> watchers = new ArrayList<>();

    @Override
    public void addWatcher(Watcher watcher) {
        if (!watchers.contains(watcher)) watchers.add(watcher);
    }

    @Override
    public void removeWatcher(Watcher watcher) {
        watchers.remove(watcher);
    }

    @Override
    public void notifyWatchers(String event) {
        // 建議複製列表防止並發修改,或用 CopyOnWriteArrayList
        for (Watcher w : new ArrayList<>(watchers)) {
            w.update(event);
        }
    }

    // 業務方法觸發通知
    public void doBusiness() {
        // ... 業務邏輯
        notifyWatchers("高興");
    }
}

5. 測試驗證

public class ObserverDemo {
    public static void main(String[] args) {
        Watched subject = new ConcreteWatched();
        subject.addWatcher(new ConcreteWatcher());
        subject.addWatcher(new ConcreteWatcher());
        subject.addWatcher(new ConcreteWatcher());
        subject.notifyWatchers("高興");  // 或 subject.doBusiness();
    }
}

進階優化方向

  1. 線程安全:觀察者列表用 CopyOnWriteArrayList 或鎖保護。
  2. 異步通知:notifyWatchers 提交到線程池,避免阻塞主題線程。
  3. 事件對象:將 String 升級為 EventObject 子類,攜帶源、時間戳、負載。
  4. 弱引用:WeakReference<Watcher> 防止觀察者無法 GC(如 GUI 組件)。
  5. Spring 整合:ApplicationEventPublisher + @EventListener 實現解耦的域事件總線。

JDK 內置支持

  • java.util.Observable / Observer(Java 9 棄用,不推薦新代碼使用)。
  • PropertyChangeSupport / PropertyChangeListener(JavaBeans 屬性變更通知)。

總結

觀察者模式核心在於主題不依賴具體觀察者,通過接口解耦。手寫版本適合輕量級場景;企業級應用建議直接使用 Spring 事件機制或成熟事件總線。掌握手寫實現,能深度理解框架底層原理。

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