觀察者模式:定義對象間一對多依賴,當一個對象 (主題/Subject) 狀態改變,所有依賴它的對象 (觀察者/Observer) 都得到通知並自動更新。屬於行為型模式。
update() 接口。// 抽象主題
public interface Subject {
void attach(Observer o);
void detach(Observer o);
void notifyObservers();
}
// 具體主題
public class ConcreteSubject implements Subject {
private List observers = new ArrayList<>();
private String state; // 業務狀態
public void attach(Observer o) { observers.add(o); }
public void detach(Observer o) { observers.remove(o); }
public void notifyObservers() {
for (Observer o : observers) o.update(); // 或 o.update(this, state)
}
// 業務方法修改狀態後通知
public void setState(String state) {
this.state = state;
notifyObservers();
}
}
// 抽象觀察者
public interface Observer {
void update(); // 或 update(Subject s, Object arg)
}
// 具體觀察者
public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) { this.name = name; }
public void update() { System.out.println(name + " notified, state changed"); }
}
// 客戶端
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
subject.attach(new ConcreteObserver("Observer1"));
subject.attach(new ConcreteObserver("Observer2"));
subject.setState("NEW_STATE"); // 觸發通知
}
將觀察者集合管理、通知邏輯上移至抽象類 Subject,具體主題僅關注業務狀態變化:
public abstract class Subject {
private List observers = new ArrayList<>();
public void attach(Observer o) { observers.add(o); }
public void detach(Observer o) { observers.remove(o); }
public void notifyObservers() {
for (Observer o : observers) o.update();
}
// 模板方法:子類實現具體狀態變更,父類負責通知
public abstract void change(String newState);
}
public class ConcreteSubject extends Subject {
private String state;
@Override
public void change(String newState) {
this.state = newState;
notifyObservers(); // 狀態變更後自動通知
}
}
// Observer/ConcreteObserver 不變
優勢:遵循「好萊塢原則」——「別調用我們,我們會調用你」;具體主題無需關心通知機制,專注業務邏輯。
public class WeatherData extends Observable {
private float temperature;
public void setTemperature(float t) {
this.temperature = t;
setChanged(); // 關鍵:標記狀態已變
notifyObservers(temperature); // 推模式:傳遞數據
}
}
public class CurrentDisplay implements Observer {
@Override
public void update(Observable o, Object arg) {
float temp = (Float) arg;
System.out.println("Current temp: " + temp);
}
}
// 註:Java 9 標記 @Deprecated(since="9"),因設計缺陷 (Observable 是類而非接口、notifyObservers 同步、無泛型)
| 方案 | 特點 | 適用場景 |
|---|---|---|
| Guava EventBus | 註解驅動 (@Subscribe)、同步/異步、死事件檢測 | 模組解耦、插件系統、Android 事件分發 |
| Spring ApplicationEvent | 容器集成、事務綁定 (@TransactionalEventListener)、異步 @Async | Spring 生態業務事件、領域事件發布 |
| RxJava / Reactor | 響應式流、背壓、操作符豐富 (map/filter/flatMap) | 高吞吐異步管道、實時數據流、移動端響應式 UI |
| Kafka / RocketMQ | 分布式、持久化、重放、順序保證 | 微服務異步通信、事件溯源、日誌聚合 |