觀察者模式定義對象間一對多依賴,當主題狀態改變時,所有依賴者自動收到通知並更新。它是事件驅動架構、MVC 模式、響應式編程的核心基石。
attach/detach/notify。notify()。update() 接口。abstract class Subject {
private List<Observer> observers = new CopyOnWriteArrayList<>(); // 線程安全
public void attach(Observer o) { observers.add(o); }
public void detach(Observer o) { observers.remove(o); }
protected void notifyObservers() { observers.forEach(Observer::update); }
public abstract void doBusiness();
}
class ConcreteSubject extends Subject {
private String state;
public void setState(String s) { state = s; doBusiness(); }
public void doBusiness() { System.out.println("State changed: " + state); notifyObservers(); }
}
interface Observer { void update(); }
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) { this.name = name; }
public void update() { System.out.println(name + " received update"); }
}
使用 CopyOnWriteArrayList 避免并發修改異常,適合多線程環境。
notify(data) 直接傳遞數據,觀察者被動接收。notify() 僅通知,觀察者主動從主題拉取所需數據,耦合度更低。java.util.Observable(已棄用)+ Observer 接口;現代開發推薦 PropertyChangeListener、Guava EventBus、RxJava、Spring ApplicationEvent。| 優點 | 缺點/風險 |
|---|---|
| 主題與觀察者抽象耦合,易擴展 | 觀察者過多導致通知風暴,性能下降 |
| 動態訂閱/取消,運行時靈活 | 循環引用導致死循環/棧溢出 |
| 符合開閉原則,新增觀察者無需改主題 | 異步通知時異常處理複雜 |
觀察者模式是構建鬆耦合、可擴展系統的基石。實戰中需關注:通知同步/異步選擇、異常隔離、防循環依賴、內存洩漏(及時 detach)、大規模場景引入專業事件總線。