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

善用 Java 內建 Observable/Observer 實作觀察者模式

     編輯:Java 程式設計入門

為什麼不自己造輪子?

Java 標準庫 java.util 提供 Observable(被觀察者)與 Observer(觀察者)介面,雖功能不及完整事件/監聽器框架強大,但在許多輕量級場合足夠使用,能節省大量開發時間。

核心類別設計

import java.util.*;

// 事件物件:攜帶訊息
class OEvent extends EventObject {
    public OEvent(String msg) { super(msg); }
}

// 觀察者:實作 Observer 介面
class OListener implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        System.err.println("Passed '" + arg + "' by " + o + " to " + this);
    }
}

// 被觀察者管理者:繼承 Observable
public class OEventManager extends Observable {
    public static void main(String[] args) {
        OEventManager mgr = new OEventManager();
        mgr.addObserver(new OListener());
        mgr.addObserver(new OListener());
        mgr.addObserver(new OListener());
        mgr.fireChange("Changed.");
    }

    // 觸發通知
    public void fireChange(String msg) {
        setChanged(); // 關鍵:標記狀態已改變
        notifyObservers(new OEvent(msg)); // 廣播事件
    }
}

關鍵細節解析

  1. setChanged() 必須調用:Observable 內部有 changed 標誌,若未呼叫 setChanged(),notifyObservers() 會被忽略,觀察者不會收到通知。這設計避免無效通知。
  2. 事件物件封裝:範例將訊息直接存入 EventObject 的 source 欄位(為簡潔起見)。正式專案建議另設欄位存放 payload,source 指向觸發事件的物件。
  3. 輸出結果:三個觀察者依序收到通知,arg 為同一 OEvent 實例。

適用性與限制

  • 優點:零依賴、API 簡單、標準庫內建、適合簡單發布/訂閱需求。
  • 限制:Observer.update(Observable, Object) 方法簽名固定,無法像自訂 Event/Listener 那樣定義強型別事件參數;Observable 是類別而非介面,限制繼承靈活性(Java 單繼承)。

結論:當介面簽名可接受時,Observable/Observer 是實用工具;複雜場景請採用自訂事件總線或 Guava EventBus、Spring ApplicationEvent 等框架。

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