前端開發模式—觀察者模式
觀察者模式 (Observer Pattern)有時候也稱為發布訂閱模式,它的核心思想是定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并被自動更新。觀察者模式是應用最廣泛的開發模式之一,MVC 三層模式中的控制器就會觀察視圖并實時更新模型部分,Vue 中也有效地使用觀察者模式來管理數據的響應式和視圖的更新。
在很多文檔中,觀察者模式的主要角色被定義如下:
- 主題接口(Subject):也叫抽象目標類或目標接口類,它提供了一個用于保存觀察者對象的聚集類和增加、刪除觀察者對象的方法,以及通知所有觀察者的抽象方法。
- 觀察者接口(Observer):它是一個抽象類或接口,它包含了一個更新自己的抽象方法,當接到具體主題的更改通知時被調用。
- 具體主題(Concrete Subject)(被觀察目標):也叫具體目標類,它是被觀察的目標,它實現抽象目標中的通知方法,當具體主題的內部狀態發生改變時,通知所有注冊過的觀察者對象。
- 具體觀察者(Concrete Observer):實現抽象觀察者中定義的抽象方法,以便在得到目標的更改通知時更新自身的狀態。
JS 中觀察者模式的實現步驟如下:
1. 定義觀察者類(訂閱者)。
// 1. 定義觀察者(訂閱者)
class Observer {
constructor(name) {
this.name = name
}
// 觀察者內部有一個更新方法,發布者通知觀察者時,會調用觀察者的更新方法
update(value) {
console.log(`${this.name}收到通知,通知內容為:${value}`)
}
}
2. 定義被觀察者類(主題、發布者、被觀察對象)。
// 2. 定義被觀察者(發布者、被觀察對象)
// 發布者內部可以添加、刪除、通知觀察者
class Subject {
constructor() {
this.observers = [] // 維護觀察者們的列表
}
// 添加觀察者
addObserver(observer) {
this.observers.push(observer)
}
// 刪除觀察者
removeObserver(observer) {
this.observers = this.observers.filter(item => item !== observer)
}
// 通知觀察者
notifyObservers(value) {
this.observers.forEach(observer => observer.update(value))
}
}
3. 生成觀察者實例對象和被觀察者的實例對象。
// 創建觀察者與發布者實例對象
const subject = new Subject()
const observer1 = new Observer('觀察者1')
const observer2 = new Observer('觀察者2')
const observer3 = new Observer('觀察者3')
4. 將觀察者實例對象們維護到被觀察者實例對象中
// 將觀察者維護到發布者中
subject.addObserver(observer1)
subject.addObserver(observer2)
subject.addObserver(observer3)
5. 被觀察者狀態改變時,通知觀察者們;觀察者們接收到通知后,進行相應的操作
subject.notifyObservers('明天房價上漲') // 觀察者1收到通知,通知內容為:明天房價上漲 觀察者2收到通知,通知內容為:明天房價上漲 觀察者3收到通知,通知內容為:明天房價上漲
subject.removeObserver(observer2)
subject.notifyObservers('明天房價下跌') // 觀察者1收到通知,通知內容為:明天房價下跌 觀察者3收到通知,通知內容為:明天房價下跌
點擊查看完整代碼
/**
* 觀察者模式
*/
// 觀察者模式
// 1. 定義觀察者(訂閱者)
// 2. 定義被觀察者(發布者、被觀察對象)
// 3. 將觀察者維護到發布者中
// 4. 被觀察者狀態改變時,通知觀察者
// 5. 觀察者接收到通知后,進行相應的操作
// 1. 定義觀察者(訂閱者)
class Observer {
constructor(name) {
this.name = name
}
// 觀察者內部有一個更新方法,發布者通知觀察者時,會調用觀察者的更新方法
update(value) {
console.log(`${this.name}收到通知,通知內容為:${value}`)
}
}
// 2. 定義被觀察者(發布者、被觀察對象)
// 發布者內部可以添加、刪除、通知觀察者
class Subject {
constructor() {
this.observers = [] // 維護觀察者列表
}
// 添加觀察者
addObserver(observer) {
this.observers.push(observer)
}
// 刪除觀察者
removeObserver(observer) {
this.observers = this.observers.filter(item => item !== observer)
}
// 通知觀察者
notifyObservers(value) {
this.observers.forEach(observer => observer.update(value))
}
}
// 創建觀察者與發布者實例對象
const subject = new Subject()
const observer1 = new Observer('觀察者1')
const observer2 = new Observer('觀察者2')
const observer3 = new Observer('觀察者3')
// 4. 將觀察者維護到發布者中
subject.addObserver(observer1)
subject.addObserver(observer2)
subject.addObserver(observer3)
// 5. 發布者下發通知,通知觀察者
subject.notifyObservers('明天房價上漲') // 觀察者1收到通知,通知內容為:明天房價上漲 觀察者2收到通知,通知內容為:明天房價上漲 觀察者3收到通知,通知內容為:明天房價上漲
subject.removeObserver(observer2)
subject.notifyObservers('明天房價下跌') // 觀察者1收到通知,通知內容為:明天房價下跌 觀察者3收到通知,通知內容為:明天房價下跌
觀察者模式的優點
解耦:觀察者模式使得主題和觀察者之間的耦合度降低,主題不需要知道觀察者的具體實現。
動態注冊:觀察者可以在運行時動態注冊和注銷,靈活性高。
廣播通知:主題可以一次性通知所有觀察者,簡化了事件處理邏輯。
觀察者模式的缺點
性能問題:如果觀察者數量較多,通知所有觀察者可能會導致性能下降。
內存泄漏:如果觀察者沒有正確注銷,可能會導致內存泄漏。
復雜性:在某些情況下,觀察者模式可能會導致系統復雜性增加,特別是在觀察者和主題之間的依賴關系較多時。
應用場景
自定義事件系統
組件間通信(如 Vue 的 EventBus)
實時數據更新(如 Websocket 消息推送)

浙公網安備 33010602011771號