定義
觀察者模式(Observer Pattern): 定義物件間一種一對多的依賴關係,使得當每一個物件改變狀態,則所有依賴於它的物件都會得到通知並自動更新。觀察者模式是一種物件行為型模式。
觀察者模式包含兩個角色:
- 主題(Subject):被觀察的物件,它維護了一個觀察者列表,可以新增、刪除觀察者,以及通知觀察者狀態的變化。
- 觀察者(Observer):觀察主題的物件,當主題狀態發生變化時,它會接收到通知並進行相應的處理。
為什麼需要觀察者模式
觀察者模式的價值在於它可以將主題物件和觀察者物件解耦,使得它們可以獨立地進行擴充套件和修改,同時也可以降低程式碼的耦合度,提高程式碼的可維護性和可擴充套件性。
具體來說,觀察者模式有以下幾個價值:
- 易於擴充套件
觀察者模式可以在不修改主題物件和觀察者物件的情況下,增加新的觀察者物件或者新的主題物件,從而實現系統的擴充套件性。
- 解耦
觀察者模式將主題物件和觀察者物件解耦,使得它們可以獨立地進行擴充套件和修改,降低了它們之間的依賴關係,提高了系統的靈活性。
- 通訊
觀察者模式透過事件通知的方式,實現了主題物件和觀察者物件之間的通訊,使得它們可以相互交流和協作,從而實現系統的功能。
總之,觀察者模式可以幫助我們更好地組織程式碼,降低程式碼的耦合度,提高程式碼的可維護性和可擴充套件性,應用廣泛,是一種非常有價值的設計模式。
具體實現
class Subject<T> {
private list: Observer<T>[] = []
constructor(private _state: T) {
}
get state() {
return this._state
}
add(observer: Observer<T>) {
this.list.push(observer)
}
remove(observer: Observer<T>) {
const index = this.list.findIndex(o => o === observer)
index > -1 && this.list.splice(index, 1)
}
notice() {
this.list.forEach(observer => {
observer.update(this)
})
}
changeState(state: T) {
this._state = state
this.notice()
}
}
class Observer<T> {
constructor(subject: Subject<T>) {
subject.add(this)
}
update(subject: Subject<T>) {
console.log('update:', subject.state)
}
}
應用場景
- DOM事件監聽
常見的如click事件、mouse事件、keyboard事件等,透過addEventListener()方法註冊事件,當事件觸發時,將自動呼叫回撥函式。 - Promise物件
Promise物件可作為一種觀察者模式實現非同步程式設計,當Promise物件狀態發生改變時,所有訂閱者都會得到通知並執行其回撥函式。