觀察者模式(Observer Pattern)是一種行為型設計模式,它定義了對象之間的一對多依賴關系,當一個對象(主題)的狀態發生改變時,所有依賴于它的對象(觀察者)都會自動收到通知并更新。
核心概念
觀察者模式包含以下核心角色:
-
?Subject(主題/被觀察者)?
- 維護觀察者列表
- 提供注冊、刪除和通知觀察者的接口
-
?ConcreteSubject(具體主題)?
- 實現Subject接口
- 管理自身狀態,并在狀態變化時通知所有觀察者
-
?Observer(觀察者)?
- 定義更新接口,接收主題通知
-
?ConcreteObserver(具體觀察者)?
- 實現Observer接口
- 根據主題的狀態變化執行具體操作
模式特點
- ?松耦合?:主題和觀察者之間松耦合
- ?自動通知?:狀態變化時自動通知觀察者
- ?一對多?:一個主題可對應多個觀察者
- ?動態訂閱?:可動態添加/刪除觀察者
應用場景
觀察者模式適用于以下場景:
- ?消息發布/訂閱系統?:如聊天室、新聞推送
- ?用戶界面組件?:GUI事件處理
- ?實時數據監控?:如股票價格變動、溫度監控
- ?事件驅動系統?:如游戲引擎、企業監控系統
- ?分布式系統?:節點狀態變更通知
代碼實現示例
以下是觀察者模式的基本實現(推模型):
// 觀察者接口
public interface Observer {void update(String message);
}// 主題接口
public interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}// 具體主題 - 新聞發布中心
public class NewsAgency implements Subject {private List<Observer> observers = new ArrayList<>();private String news;public void setNews(String news) {this.news = news;notifyObservers();}public void registerObserver(Observer o) {observers.add(o);}public void removeObserver(Observer o) {observers.remove(o);}public void notifyObservers() {for (Observer o : observers) {o.update(news);}}
}// 具體觀察者 - 新聞訂閱者
public class NewsSubscriber implements Observer {private String name;public NewsSubscriber(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " 收到新聞: " + message);}
}
通知模型對比
觀察者模式有兩種主要的通知模型:
模型類型 | 數據傳遞方式 | 優點 | 缺點 |
---|---|---|---|
推模型 | 主題主動推送詳細數據給觀察者 | 實時性強,響應快 | 可能傳遞冗余數據 |
拉模型 | 觀察者收到通知后主動拉取數據 | 按需獲取,靈活性高 | 增加主題的訪問壓力 |
Java內置支持
Java在java.util
包中提供了觀察者模式的實現:
Observable
類(主題)Observer
接口
但自Java 9起已被標記為@Deprecated
,推薦使用java.beans
包中的PropertyChangeListener
和PropertyChangeSupport
。
優缺點分析
?優點?:
- 主題和觀察者之間松耦合
- 支持廣播通信
- 符合開放-封閉原則
- 可動態添加/刪除觀察者
?缺點?:
- 通知順序不可控
- 觀察者過多時可能影響性能
- 可能導致循環依賴
- 觀察者不知道彼此存在,可能導致更新沖突
實際應用案例
- ?聊天系統?:聊天室作為主題,用戶作為觀察者
- ?溫度監控系統?:溫度傳感器作為主題,顯示設備和報警系統作為觀察者
- ?彩票系統?:彩票中心作為主題,購彩者作為觀察者
- ?企業監控系統?:員工電腦作為主題,安全模塊作為觀察者