觀察者模式定義對象間一對多依賴,當主題狀態改變時自動通知所有觀察者。本文展示自定義實現(推薦)與 JDK 內置 Observable/Observer(已棄用)兩種方式,並解析 Servlet Filter、消息隊列中的實戰應用。
// 觀察者介面
interface Observer {
void update(Subject subject);
}
// 主題(被觀察者)抽象類
abstract class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer o) { observers.add(o); }
public void removeObserver(Observer o) { observers.remove(o); }
protected void notifyAllObservers() {
for (Observer o : observers) o.update(this);
}
}
// 具體主題:新聞廣播
class NewsSubject extends Subject {
private String news;
public void setNews(String news) {
this.news = news;
System.out.println("廣播發布新聞:" + news);
notifyAllObservers();
}
public String getNews() { return news; }
}
// 具體觀察者:訂閱用戶
class UserObserver implements Observer {
private String name;
public UserObserver(String name) { this.name = name; }
public void update(Subject subject) {
String news = ((NewsSubject)subject).getNews();
System.out.println(name + " 收到新聞:" + news + " → 做出反應");
}
}
// 客戶端
public class Demo {
public static void main(String[] args) {
NewsSubject subject = new NewsSubject();
subject.addObserver(new UserObserver("用戶A"));
subject.addObserver(new UserObserver("用戶B"));
subject.addObserver(new UserObserver("用戶C"));
subject.setNews("今日天氣晴朗");
}
}
/* 輸出:
廣播發布新聞:今日天氣晴朗
用戶A 收到新聞:今日天氣晴朗 → 做出反應
用戶B 收到新聞:今日天氣晴朗 → 做出反應
用戶C 收到新聞:今日天氣晴朗 → 做出反應
*/
// 繼承 java.util.Observable
class JdkNews extends Observable {
public void setNews(String news) {
setChanged(); // 必須調用,標記狀態已變
notifyObservers(news); // 推模式:直接傳遞數據
}
}
// 實現 java.util.Observer
class JdkUser implements Observer {
public void update(Observable o, Object arg) {
System.out.println("JDK觀察者收到:" + arg);
}
}
// 使用
JdkNews news = new JdkNews();
news.addObserver(new JdkUser());
news.setNews("JDK 內置觀察者");
棄用原因:Observable 是類而非介面,限制復用;notifyObservers 同步阻塞;無線程安全保證。建議自定義或使用事件總線。
FilterChain.doFilter 類似通知下一個觀察者ApplicationEventPublisher + @EventListenerExecutorService 提交通知任務,避免阻塞發布者WeakReference<Observer>)| 維度 | 觀察者模式 | 發布訂閱模式 |
|---|---|---|
| 耦合度 | 主題持有觀察者引用 | 通過事件通道/總線完全解耦 |
| 同步性 | 通常同步 | 通常異步 |
| 跨進程 | 不支援 | 支援(消息中間件) |
觀察者模式是事件驅動架構的基石,掌握其核心與變體,能構建高內聚低耦合的系統。