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)); // 廣播事件
}
}
Observable 內部有 changed 標誌,若未呼叫 setChanged(),notifyObservers() 會被忽略,觀察者不會收到通知。這設計避免無效通知。EventObject 的 source 欄位(為簡潔起見)。正式專案建議另設欄位存放 payload,source 指向觸發事件的物件。arg 為同一 OEvent 實例。Observer.update(Observable, Object) 方法簽名固定,無法像自訂 Event/Listener 那樣定義強型別事件參數;Observable 是類別而非介面,限制繼承靈活性(Java 單繼承)。結論:當介面簽名可接受時,Observable/Observer 是實用工具;複雜場景請採用自訂事件總線或 Guava EventBus、Spring ApplicationEvent 等框架。