設計模式之—觀察者模式
一:概念:
觀察者模式,屬於行為型模式的一種,它定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態變化時,會通知所有的觀察者對象,使他們能夠自動更新自己。
注意:有些人認為觀察者模式就是發布訂閱模式,但實際上觀察者模式和發布訂閱模式是有區別的。
區別:觀察者模式只有兩個,一個是觀察者一個是被觀察者。發布訂閱模式不一樣,發布訂閱模式還有一個中間層,發布訂閱模式的實現是,發布者通知給中間層 => 中層接受並通知訂閱者 => 訂閱者收到通知並發生變化
如下圖所示:
上圖左邊是觀察者模式右邊是發布訂閱模式
二:解釋
舉個栗子:
以學生為例,上課和下課的鈴聲就是被觀察者,學生就是觀察者,當下課鈴聲響了,學生就知道下課了,就出去跑着玩了,然后過了10分鍾,上課鈴聲又響了,然后學生聽到上課鈴,又開始從外面往教室跑,去上課。
其實我們在平時也用到過觀察者模式,只是我們沒有注意到而已,舉一個簡單的例子:我們曾經在DOM節點上面綁定過事件函數,那我們就使用過觀察者模式,因為JS和DOM之間就是實現了一種觀察者模式。
document.body.addEventListener("click", function() { alert("Hello World") },false ) document.body.click() //模擬用戶點擊
以上js就是觀察者,DOM就是被觀察者,給DOM添加點擊事件就相當於訂閱了DOM,當DOM被點擊,DOM就會通知js觸發‘ alert("Hello World") ’
在實際項目中,我們所用的vue框架就采用了這種觀察者模式的思想,下面我們模仿一下vue的v-model雙向綁定的實現:
// 創建對象 var targetObj = { name:'小李' } var targetObj2 = { name:'小李' } // 定義值改變時的處理函數(觀察者) function observer(oldVal, newVal) { // 其他處理邏輯... targetObj2.name = newVal console.info('targetObj2的name屬性的值改變為 ' + newVal); } // 定義name屬性及其set和get方法(name屬性為被觀察者) Object.defineProperty(targetObj, 'name', { enumerable: true, configurable: true, get: function() { return name; }, set: function(val) { //調用處理函數 observer(name, val) name = val } }); targetObj.name = '張三'; targetObj.name = '李四'; console.log(targetObj2.name)
以上代碼輸出的結果為:
可以看出,雖然我們只是改變了targetObj的name屬性,但是因為觀察者模式的設計,targetObj2的name屬性同樣被改變,這就實現了一個簡單的觀察者模式。
參考: