🌟觀察者模式 vs 發布訂閱模式詳解教程
收藏 + 點贊 + 關注,持續更新高頻面試知識庫!🚀
一、核心概念(總)
在軟件開發中,觀察者模式(Observer) 和 發布訂閱模式(Publish-Subscribe) 經常被提及。二者非常相似,都屬于行為型設計模式,核心思想是:解耦發送者與接收者。
但它們在實際使用中又有細微區別,理解清楚能幫助我們在業務代碼、框架設計、架構層面靈活應用。
二、核心區別(分)
特性 | 觀察者模式(Observer) | 發布-訂閱模式(Pub-Sub) |
---|---|---|
角色 | 主題(Subject)+ 觀察者(Observer) | 發布者(Publisher)+ 訂閱者(Subscriber)+ 中間人(Broker) |
依賴 | 觀察者直接依賴主題 | 訂閱者不依賴發布者,通過事件中心解耦 |
通信 | 一對多,通知直接發送 | 完全解耦,依賴消息通道 |
場景 | GUI、數據綁定、狀態變化監聽 | 消息隊列、微服務、系統解耦 |
👉 簡單理解:
觀察者模式更偏同步直接通知,發布訂閱更偏異步消息總線。
三、具體講解(深入分解)
1?? 觀察者模式詳解
📌 設計結構:
- Subject(被觀察者):維護觀察者列表,狀態變更時通知觀察者。
- Observer(觀察者):接收通知并做出相應處理。
📌 適用場景:
- UI 組件更新
- Vue 響應式系統(2.x 的 Dep)
- 數據流監聽
📌 示例代碼(JavaScript 實現)
// 主題(被觀察者)
class Subject {constructor() {this.observers = [];}addObserver(observer) {this.observers.push(observer);}removeObserver(observer) {this.observers = this.observers.filter(o => o !== observer);}notify(data) {this.observers.forEach(observer => observer.update(data));}
}// 觀察者
class Observer {constructor(name) {this.name = name;}update(data) {console.log(`${this.name} 收到通知: ${data}`);}
}// 使用示例
const subject = new Subject();const observer1 = new Observer("觀察者A");
const observer2 = new Observer("觀察者B");subject.addObserver(observer1);
subject.addObserver(observer2);subject.notify("數據更新了!");
? 輸出:
觀察者A 收到通知: 數據更新了!
觀察者B 收到通知: 數據更新了!
2?? 發布-訂閱模式詳解
📌 設計結構:
- Publisher(發布者):發送事件。
- Subscriber(訂閱者):監聽事件。
- EventBus(事件中心):負責消息分發,中間層解耦了兩者。
📌 適用場景:
- Vue / React 全局事件管理
- 微服務架構中的消息總線
- 復雜模塊解耦
📌 示例代碼(JavaScript 實現)
// 簡易 EventBus 實現
class EventBus {constructor() {this.events = {};}subscribe(event, callback) {if (!this.events[event]) this.events[event] = [];this.events[event].push(callback);}unsubscribe(event, callback) {this.events[event] = this.events[event].filter(cb => cb !== callback);}publish(event, data) {if (!this.events[event]) return;this.events[event].forEach(callback => callback(data));}
}// 使用示例
const bus = new EventBus();function listenerA(data) {console.log('監聽器A 收到:', data);
}
function listenerB(data) {console.log('監聽器B 收到:', data);
}bus.subscribe('news', listenerA);
bus.subscribe('news', listenerB);bus.publish('news', '有新消息發布!');
? 輸出:
監聽器A 收到: 有新消息發布!
監聽器B 收到: 有新消息發布!
四、總結對比(總)
對比維度 | 觀察者模式 | 發布訂閱模式 |
---|---|---|
通信方式 | 主動通知 | 中介通知 |
耦合度 | 存在一定耦合 | 完全解耦 |
適用復雜度 | 輕量簡單 | 更適合大型系統 |
使用典型 | Vue 2 響應式、數據綁定 | Vue3 mitt、EventBus、微服務消息 |
? 面試建議
- 先講兩者共同點(解耦通知)
- 再講關鍵區別(是否通過中間層)
- 最后補充應用場景(Vue、React、微服務)
五、推薦面試金句
“觀察者模式是一種直接訂閱、直接通知的同步模型,而發布訂閱模式通過中介(事件總線)實現完全解耦**,更適用于復雜系統模塊通信。”**