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

Java 觀察者模式入門教程:從定義到完整代碼實現

     編輯:Java 相關知識

什麼是觀察者模式?

觀察者模式是一種行為型設計模式,定義對象間「一對多」依賴關係:當主題對象狀態發生變化,所有註冊的觀察者對象自動收到通知並做出響應。就像訂閱報紙:報社(主題)出版新報,所有訂戶(觀察者)自動收到。

核心角色

  • Subject(主題/被觀察者):維護觀察者列表,提供註冊/移除/通知接口。
  • Observer(觀察者):定義更新接口 update(event),收到通知時執行具體邏輯。
  • ConcreteSubject:具體主題,業務狀態變化時調用 notifyObservers()。
  • ConcreteObserver:具體觀察者,實現 update() 處理具體業務響應。

接口定義

// 觀察者接口
public interface Observer {
    void update(Object event);
}

// 主題接口
public interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers(Object event);
}

具體實現

主題實現類

public class ConcreteSubject implements Subject {
    private final List<Observer> observers = new ArrayList<>();

    @Override
    public void attach(Observer observer) {
        if (observer != null && !observers.contains(observer)) {
            observers.add(observer);
        }
    }

    @Override
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(Object event) {
        for (Observer obs : observers) {
            obs.update(event);
        }
    }
}

觀察者實現類

public class ConcreteObserver implements Observer {
    private final String name;

    public ConcreteObserver(String name) { this.name = name; }

    @Override
    public void update(Object event) {
        System.out.println(name + " 收到通知: " + event);
    }
}

客戶端測試

public class Main {
    public static void main(String[] args) {
        Subject subject = new ConcreteSubject();

        Observer obs1 = new ConcreteObserver("觀察者A");
        Observer obs2 = new ConcreteObserver("觀察者B");
        Observer obs3 = new ConcreteObserver("觀察者C");

        subject.attach(obs1);
        subject.attach(obs2);
        subject.attach(obs3);

        System.out.println("=== 第一次通知 ===");
        subject.notifyObservers("事件: 系統啟動完成");

        subject.detach(obs2);
        System.out.println("=== 移除觀察者B後 ===");
        subject.notifyObservers("事件: 配置已更新");
    }
}

運行結果

=== 第一次通知 ===
觀察者A 收到通知: 事件: 系統啟動完成
觀察者B 收到通知: 事件: 系統啟動完成
觀察者C 收到通知: 事件: 系統啟動完成
=== 移除觀察者B後 ===
觀察者A 收到通知: 事件: 配置已更新
觀察者C 收到通知: 事件: 配置已更新

關鍵點總結

  1. 鬆耦合:主題只依賴 Observer 接口,不依賴具體觀察者類。
  2. 廣播通知:一次狀態變化觸發所有觀察者更新。
  3. 動態訂閱:運行時可隨時 attach/detach 觀察者。
  4. 單向依賴:觀察者知道主題(通常持有引用),主題不知觀察者細節。

常見應用場景

  • GUI 事件監聽(按鈕點擊、滑鼠移動)
  • 消息隊列消費者註冊
  • 緩存失效通知其他節點更新
  • 日誌/審計系統訂閱業務事件
  • 股價變動通知投資者

JDK 與框架支持

Java 內置 java.util.Observable/Observer(已棄用),推薦使用 PropertyChangeSupport 或 Spring ApplicationEventPublisher、Guava EventBus、RxJava 等成熟實現,提供線程安全、異步、異常隔離等能力。

練習建議

嘗試擴展:
1. 事件分類通知(不同類型事件通知不同觀察者組)
2. 異步通知(線程池執行 update)
3. 觀察者優先級(按優先級順序通知)
4. 通知過濾(觀察者聲明關心的事件類型)

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