JavaScript設計模式之觀察者模式

前言

準備研究一下MVVM的一些東西,由于MVVM運用了觀察者模式的思想,因此翻開了《JavaScript設計模式與開發(fā)實踐》一書,將觀察者模式學習了一遍,順便有對一些常用的設計模式進行一些了解,但還是有很多不能理解的地方,還需努力啊。

一、什么是觀察者模式

觀察者模式又叫做發(fā)布—訂閱模式,是我們最常用的設計模式之一。它定義對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都將得到通知和更新。觀察者模式提供了一個訂閱模型,其中對象訂閱事件并在發(fā)生時得到通知,這種模式是事件驅動的編程基石,它有利益于良好的面向對象的設計。

看了上面的這段描述,可能還是不懂什么是觀察者模式。我們還可以來看看生活中的觀察者模式:現在房價這么高,你肯定是想要早點買房,但你看好的樓盤還沒開盤,因此你就將你的電話留給售樓小姐,一旦樓盤推出就讓她打電話給你。主動權在售樓方,而你只需要提供一個聯系方式就行了這樣你就不用擔心樓盤出來你不知道了,也不需要每天都打電話去問樓盤推出了沒。

二、觀察者模式的使用場景

2.1 DOM事件

實際上,只要我們曾經在DOM節(jié)點上面綁定過事件函數,那我們就使用過觀察者模式,應為JS和DOM之間就是實現了一種觀察者模式。

document.body.addEventListener("click", function() {
    alert("Hello World")
},false )
document.body.click() //模擬用戶點擊

在上面的代碼中,需要監(jiān)聽用戶點擊 document.body 的動作,但是我們是沒辦法預知用戶將在什么時候點擊的。因此我們訂閱了 document.body 的 click 事件,當 body 節(jié)點被點擊時,body 節(jié)點便會向訂閱者發(fā)布 "Hello World" 消息。

2.2自定義事件

除了DOM事件外,我們還可以實現一些自定義事件,這種依靠自定義時間完成的觀察者模式可以用于任何的JavaScript代碼中。

示例:

const event = {
    clientList: [],
    listen: function(key , fn) {
        if (this.clientListen[key]) {
            this.clientList[key] = []
        }
        this.clientList[key].push(fn)
    },
    trigger: function() {
        const key = Array.prototype.shift.call(arguments)
        const fns = this.clientList[key]
        if (!fns || fns.length === 0 ) {
            return false
        }
        for (let i = 0, fn ;fn = fns[i++];) {
            fn.apply(this, arguments)
        }
    },
    remove : function(key , fn) {
        const fns = this.clientList[key]
        if (!fns) {
            return false
        }
        if (!fn) {
            fns && (fns.length = 0)
        } else {
            for (let l = fns.length - 1; l>=0; l--) {
                const _fn = fns[l]
                if ( _fn ===fn) {
                    fns.splice(l, 1)
                }
            }
        }
}

const installEvent = (obj) => {
    for (let i in event) {
        obj[i] = event[i]
    }
}

然后就能增加發(fā)布和訂閱功能了:

const events = {}
installEvent(events)
// 訂閱信息
events.listen('newMessage',fn1 = (say) => {
    console.log('say:' + say)
})
// 發(fā)布信息
events.trigger('newMessage',"Hello world")
//移除訂閱
events.remove('newMessage',fn1)

三、觀察者模式的不足

觀察者模式的有點非常明顯:一是時間上的解耦,而是對象之間的解耦。既可用于異步編程中,也可以用幫助我們完成更松耦合的代碼編寫。但它仍然有所不足:

  • 創(chuàng)建訂閱者本身要消耗一定的時間和內存
  • 當訂閱一個消息時,也許此消息并沒有發(fā)生,但這個訂閱者會始終存在內存中。
  • 觀察者模式弱化了對象之間的聯系,這本是好事情,但如果過度使用,對象與對象之間的聯系也會被隱藏的很深,會導致項目的難以跟蹤維護和理解。

原文鏈接JavaScript設計模式之觀察者模式

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 8,131評論 2 17
  • ??JavaScript 與 HTML 之間的交互是通過事件實現的。 ??事件,就是文檔或瀏覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,701評論 1 11
  • 實現收入指數型增長的第三個關鍵點,我們總結為強行融入更好的圈子。 有個朋友發(fā)微信朋友圈得瑟,說竟然發(fā)現跟王石在同一...
    承謙閱讀 219評論 0 0
  • 窗外的夜色慢慢蔓延,星光開始點綴這片漆黑的夜空。天空的西北角掛著一輪新月被無聊的閑云調弄著,空氣中伴隨著大雨初霽的...
    木樨Leo閱讀 599評論 13 4
  • 本文是一個系列的三篇文章里的第三篇,如果沒看過前兩篇,可以先點擊鏈接看我在簡書發(fā)的前兩篇: 1,《同樣的環(huán)境,為何...
    河南張宏濤閱讀 14,906評論 0 20

友情鏈接更多精彩內容