[GoF] 觀察者模式 Observer
此篇為各筆記之整理,非原創內容,資料來源主要為:
- 《JavaScript 設計模式與開發實踐》
- Observer Pattern @ patterns.dev
TL;DR
觀察者模式,當一個物件的狀態發生改變時,所有依賴於它的物件都將得到通知。
概念
在沒有使用觀察者模式前,如果想要追蹤某個物件的狀態是否有發生變化時,必須不斷的去詢問與查詢該物件狀態;但透過觀察者模式,一旦主體(subject)發生改變(或其他合適的時機),它會主動 通知所有訂閱該主題的訂閱者。
舉例來說,如果有用過 react-hook-form 這個套件的話,如果想要知道表單最新的資料狀態時,可以主動使用 getValues('firstName')
來取出表單的值;但如果我們時希望表單一有更新就通知我們的話,則可以使用它所提供的 watch
方法,這個 watch('firstName')
的使用,就是觀察者模式,但 watch 的對象的資料狀態發生改變時,它就會主動通知元件,並得到最新的資料狀態。
名詞解釋
observable(又稱 subject)通常會具有下列功能和元素:
observer
:通常是可以被執行的「函式」,或者是物件中帶有可被執行的函式。當收到通知(notification)時,會觸發執行 observer。又常稱作subscriber
或listener
。subscribe()
:用來把 observer 加入 observers 陣列中的方法unsubscribe()
:用來把 observer 從 observers 陣列中移除的方法notify()
:一旦呼叫此方法,則所有該 observable 中的 observers 都會被執行。又常稱作dispatch()
或broadcast()
。
提示
observable (subject) 可以想成是帶有上述這些元素的一個東東。
常見的觀察者模式
DOM 事件
實際上,很常使用到的 addEventListener
就類似 observer pattern:
btn.addEventListener('click', () => {
// ...
});
- onClick 中的 callback function 就類似 observer pattern 中的 observer
- addEventListener 就類似 observer pattern 中的
subscribe()
- btn 就像是 subject
Redux
Redux Store 最基本的程式邏輯也是利用 observer pattern 來通知所有訂閱到該資料的元件要 re-render。可以參考官方文件 Inside a Redux Store。