觀察者模式 屬於行為型模式。它定義對象間的一種一對多依賴關係,當一個對象 (Subject/Observable) 狀態發生改變時,所有依賴它的對象 (Observer) 都會得到通知並自動更新。廣泛用於事件處理系統、GUI、消息推送、模型-視圖分離 (MVC)。
java.util.Observable 類 (已棄用) 和 java.util.Observer 接口 (已棄用),現代建議自定義或使用事件總線 (Guava EventBus, Spring ApplicationEvent)。update(Observable o, Object arg)。
// 1. 自定義 Observable (替代已棄用的 JDK 類)
public class Product {
private String name;
private float price;
private final List observers = new ArrayList<>();
public void addObserver(Observer o) { observers.add(o); }
public void removeObserver(Observer o) { observers.remove(o); }
public void setPrice(float price) {
this.price = price;
notifyObservers(new PriceChangeEvent(this, price)); // 發送事件對象
}
private void notifyObservers(Object event) {
for (Observer o : observers) {
o.update(this, event);
}
}
// getter...
}
// 2. 事件對象 (攜帶變更詳情)
public class PriceChangeEvent {
private final Product product;
private final float newPrice;
public PriceChangeEvent(Product p, float price) { this.product = p; this.newPrice = price; }
// getter...
}
// 3. 觀察者接口
public interface Observer {
void update(Object source, Object event);
}
// 4. 具體觀察者:郵件通知、日誌記錄、緩存刷新
public class EmailNotifier implements Observer {
@Override
public void update(Object source, Object event) {
if (event instanceof PriceChangeEvent) {
PriceChangeEvent e = (PriceChangeEvent) event;
System.out.println("發送郵件: 商品 " + e.getProduct().getName() + " 價格變為 " + e.getNewPrice());
}
}
}
public class CacheRefresher implements Observer {
@Override
public void update(Object source, Object event) {
if (event instanceof PriceChangeEvent) {
System.out.println("刷新商品緩存: " + ((PriceChangeEvent)event).getProduct().getName());
}
}
}
// 5. 客戶端
public class Client {
public static void main(String[] args) {
Product product = new Product("iPhone 15", 7999);
product.addObserver(new EmailNotifier());
product.addObserver(new CacheRefresher());
product.setPrice(7799); // 觸發通知
}
}
notifyObservers(event) 直接傳遞變更數據 (如上例),觀察者被動接收。notifyObservers() 僅通知,觀察者主動從 Subject 獲取感興趣數據。耦合度較高但數據傳輸可控。ApplicationEventPublisher 發布事件,@EventListener 監聽,支持異步、事務綁定。@Subscribe。Observable/Flowable 流式處理,支持背壓、操作符組合。