亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

淺談發布訂閱模式與觀察者模式

2024-05-06 16:49:43
字體:
來源:轉載
供稿:網友

背景

設計模式并非是軟件開發的專業術語,實際上,“模式”最早誕生于建筑學。

設計模式的定義是:在面向對象軟件設計過程中針對特定問題的簡潔而優雅的解決方案。通俗一點說,設計模式是在某種場合下對某個問題的一種解決方案。如果再通俗一點說,設計模式就是給面向對象軟件開發中的一些好的設計取個名字。

這些“好的設計”并不是誰發明的,而是早已存在于軟件開發中。一個稍有經驗的程序員也許在不知不覺中數次使用過這些設計模式。GoF(Gang of Four--四人組,《設計模式》幾位作者)最大的功績是把這些“好的設計”從浩瀚的面向對象世界中挑選出來,并且給予它們一個好聽又好記的名字。

設計模式并不直接用來完成代碼的編寫,而是描述在各種不同情況下,要怎么解決問題的一種方案,他不是一個死的機制,他是一種思想,一種寫代碼的形式。每種語言對于各種設計模式都有他們自己的實現方式,對于某些設計模式來說,可能在某些語言下并不適用,比如工廠方法模式對于javascript。模式應該用在正確的地方。而哪些才算正確的地方,只有在我們深刻理解了模式的意圖之后,再結合項目的實際場景才會知道。。

模式的社區一直在發展。GoF在1995年提出了23種設計模式,但模式不僅僅局限于這23種,后面增加到了24種。在這20多年的時間里,也許有更多的模式已經被人發現并總結了出來,比如一些JavaScript 圖書中會提到模塊模式、沙箱模式等。這些“模式”能否被世人公認并流傳下來,還有待時間驗證。

觀察者模式(Observer Pattern)

觀察者模式定義了對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都將得到通知,并自動更新。觀察者模式屬于行為型模式,行為型模式關注的是對象之間的通訊,觀察者模式就是觀察者和被觀察者之間的通訊。

觀察者模式有一個別名叫“發布-訂閱模式”,或者說是“訂閱-發布模式”,訂閱者和訂閱目標是聯系在一起的,當訂閱目標發生改變時,逐個通知訂閱者。我們可以用報紙期刊的訂閱來形象的說明,當你訂閱了一份報紙,每天都會有一份最新的報紙送到你手上,有多少人訂閱報紙,報社就會發多少份報紙,報社和訂報紙的客戶就是上面文章開頭所說的“一對多”的依賴關系。

發布訂閱模式(Pub-Sub Pattern)

其實24種基本的設計模式中并沒有發布訂閱模式,上面也說了,他只是觀察者模式的一個別稱。

但是經過時間的沉淀,似乎他已經強大了起來,已經獨立于觀察者模式,成為另外一種不同的設計模式。

在現在的發布訂閱模式中,稱為發布者的消息發送者不會將消息直接發送給訂閱者,這意味著發布者和訂閱者不知道彼此的存在。在發布者和訂閱者之間存在第三個組件,稱為消息代理或調度中心或中間件,它維持著發布者和訂閱者之間的聯系,過濾所有發布者傳入的消息并相應地分發它們給訂閱者。

舉一個例子,你在微博上關注了A,同時其他很多人也關注了A,那么當A發布動態的時候,微博就會為你們推送這條動態。A就是發布者,你是訂閱者,微博就是調度中心,你和A是沒有直接的消息往來的,全是通過微博來協調的(你的關注,A的發布動態)。

觀察者模式和發布訂閱模式有什么區別?

我們先來看下這兩個模式的實現結構:

發布訂閱模式,觀察者模式

觀察者模式:觀察者(Observer)直接訂閱(Subscribe)主題(Subject),而當主題被激活的時候,會觸發(Fire Event)觀察者里的事件。

發布訂閱模式:訂閱者(Subscriber)把自己想訂閱的事件注冊(Subscribe)到調度中心(Topic),當發布者(Publisher)發布該事件(Publish topic)到調度中心,也就是該事件觸發時,由調度中心統一調度(Fire Event)訂閱者注冊到調度中心的處理代碼。

我們再來看下這兩個模式的代碼案例:(獵人發布與訂閱任務)

觀察者模式:

  //有一家獵人工會,其中每個獵人都具有發布任務(publish),訂閱任務(subscribe)的功能  //他們都有一個訂閱列表來記錄誰訂閱了自己  //定義一個獵人類  //包括姓名,級別,訂閱列表  function Hunter(name, level){    this.name = name    this.level = level    this.list = []  }  Hunter.prototype.publish = function (money){    console.log(this.level + '獵人' + this.name + '尋求幫助')    this.list.forEach(function(item, index){      item(money)    })  }  Hunter.prototype.subscribe = function (targrt, fn){    console.log(this.level + '獵人' + this.name + '訂閱了' + targrt.name)    targrt.list.push(fn)  }    //獵人工會走來了幾個獵人  let hunterMing = new Hunter('小明', '黃金')  let hunterJin = new Hunter('小金', '白銀')  let hunterZhang = new Hunter('小張', '黃金')  let hunterPeter = new Hunter('Peter', '青銅')    //Peter等級較低,可能需要幫助,所以小明,小金,小張都訂閱了Peter  hunterMing.subscribe(hunterPeter, function(money){    console.log('小明表示:' + (money > 200 ? '' : '暫時很忙,不能') + '給予幫助')  })  hunterJin.subscribe(hunterPeter, function(){    console.log('小金表示:給予幫助')  })  hunterZhang.subscribe(hunterPeter, function(){    console.log('小張表示:給予幫助')  })    //Peter遇到困難,賞金198尋求幫助  hunterPeter.publish(198)    //獵人們(觀察者)關聯他們感興趣的獵人(目標對象),如Peter,當Peter有困難時,會自動通知給他們(觀察者)

發布訂閱模式:

  //定義一家獵人工會  //主要功能包括任務發布大廳(topics),以及訂閱任務(subscribe),發布任務(publish)  let HunterUnion = {    type: 'hunt',    topics: Object.create(null),    subscribe: function (topic, fn){      if(!this.topics[topic]){         this.topics[topic] = [];       }      this.topics[topic].push(fn);    },    publish: function (topic, money){      if(!this.topics[topic])         return;      for(let fn of this.topics[topic]){        fn(money)      }    }  }    //定義一個獵人類  //包括姓名,級別  function Hunter(name, level){    this.name = name    this.level = level  }  //獵人可在獵人工會發布訂閱任務  Hunter.prototype.subscribe = function (topic, fn){    console.log(this.level + '獵人' + this.name + '訂閱了狩獵' + topic + '的任務')    HunterUnion.subscribe(topic, fn)  }  Hunter.prototype.publish = function (topic, money){    console.log(this.level + '獵人' + this.name + '發布了狩獵' + topic + '的任務')    HunterUnion.publish(topic, money)  }    //獵人工會走來了幾個獵人  let hunterMing = new Hunter('小明', '黃金')  let hunterJin = new Hunter('小金', '白銀')  let hunterZhang = new Hunter('小張', '黃金')  let hunterPeter = new Hunter('Peter', '青銅')    //小明,小金,小張分別訂閱了狩獵tiger的任務  hunterMing.subscribe('tiger', function(money){    console.log('小明表示:' + (money > 200 ? '' : '不') + '接取任務')  })  hunterJin.subscribe('tiger', function(money){    console.log('小金表示:接取任務')  })  hunterZhang.subscribe('tiger', function(money){    console.log('小張表示:接取任務')  })  //Peter訂閱了狩獵sheep的任務  hunterPeter.subscribe('sheep', function(money){    console.log('Peter表示:接取任務')  })    //Peter發布了狩獵tiger的任務  hunterPeter.publish('tiger', 198)    //獵人們發布(發布者)或訂閱(觀察者/訂閱者)任務都是通過獵人工會(調度中心)關聯起來的,他們沒有直接的交流。

觀察者模式和發布訂閱模式最大的區別就是發布訂閱模式有個事件調度中心。

觀察者模式由具體目標調度,每個被訂閱的目標里面都需要有對觀察者的處理,這種處理方式比較直接粗暴,但是會造成代碼的冗余。

而發布訂閱模式中統一由調度中心進行處理,訂閱者和發布者互不干擾,消除了發布者和訂閱者之間的依賴。這樣一方面實現了解耦,還有就是可以實現更細粒度的一些控制。比如發布者發布了很多消息,但是不想所有的訂閱者都接收到,就可以在調度中心做一些處理,類似于權限控制之類的。還可以做一些節流操作。

觀察者模式是不是發布訂閱模式

網上關于這個問題的回答,出現了兩極分化,有認為發布訂閱模式就是觀察者模式的,也有認為觀察者模式和發布訂閱模式是真不一樣的。

其實我不知道發布訂閱模式是不是觀察者模式,就像我不知道辨別模式的關鍵是設計意圖還是設計結構(理念),雖然《JavaScript設計模式與開發實踐》一書中說了分辨模式的關鍵是意圖而不是結構

如果以結構來分辨模式,發布訂閱模式相比觀察者模式多了一個中間件訂閱器,所以發布訂閱模式是不同于觀察者模式的;如果以意圖來分辨模式,他們都是實現了對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都將得到通知,并自動更新,那么他們就是同一種模式,發布訂閱模式是在觀察者模式的基礎上做的優化升級。

不過,不管他們是不是同一個設計模式,他們的實現方式確實有差別,我們在使用的時候應該根據場景來判斷選擇哪個。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国偷自产在线视频| 国产一区二区日韩| 海角国产乱辈乱精品视频| 日韩综合中文字幕| 日韩国产欧美精品在线| 久久91精品国产| 日本免费久久高清视频| 亚洲精品mp4| 亚洲精品色婷婷福利天堂| 中文字幕精品久久| 美女福利视频一区| 久久久免费在线观看| 中文字幕亚洲综合久久筱田步美| 国产不卡av在线| 日韩av电影手机在线| 亚洲国产精彩中文乱码av在线播放| 亚洲精品美女在线观看| 国内精品久久久| 97福利一区二区| 成人黄色在线播放| 国产精品r级在线| 国产不卡精品视男人的天堂| 亚洲aⅴ日韩av电影在线观看| 91福利视频在线观看| 中文字幕亚洲欧美一区二区三区| 成人福利在线观看| 蜜月aⅴ免费一区二区三区| 最近中文字幕mv在线一区二区三区四区| 亚洲精品一区中文字幕乱码| 91久久中文字幕| 91免费人成网站在线观看18| 欧美日韩国产精品一区二区不卡中文| 欧美性xxxx| 国产精品中文久久久久久久| 亚洲成色777777在线观看影院| 日韩在线观看免费| 亚洲黄色在线看| 日韩中文字幕免费| 国产69精品久久久久99| 插插插亚洲综合网| 国产日本欧美视频| 性欧美在线看片a免费观看| 久久久av亚洲男天堂| 国外成人在线直播| 91久久国产精品91久久性色| 亚洲偷熟乱区亚洲香蕉av| 在线看国产精品| 欧美精品18videos性欧| 国产精品私拍pans大尺度在线| 97视频在线观看免费高清完整版在线观看| 欧美成人剧情片在线观看| 亚洲国产精品久久久久秋霞蜜臀| 久久不射电影网| 亚洲精品成人久久久| 成人在线国产精品| 亚洲国产古装精品网站| 成人av.网址在线网站| 欧美在线视频导航| 欧美一级视频一区二区| 亚洲午夜精品久久久久久久久久久久| 精品成人乱色一区二区| 欧美国产亚洲视频| 国产日产久久高清欧美一区| 性欧美xxxx交| 日韩精品视频在线观看网址| 国产一区二区三区精品久久久| 大伊人狠狠躁夜夜躁av一区| 亚洲一区国产精品| 日韩在线国产精品| 欧美精品videofree1080p| 草民午夜欧美限制a级福利片| 亚洲国产精品久久久久秋霞蜜臀| 国产视频精品xxxx| 国产在线不卡精品| 亚洲人成在线电影| 欧美又大粗又爽又黄大片视频| 欧美视频国产精品| 国产日韩中文在线| 日本免费久久高清视频| 亚洲激情久久久| 亚洲精品国产综合区久久久久久久| 久久精品国产久精国产一老狼| 精品国产一区二区三区久久狼黑人| 欧美一级大胆视频| 国产精品视频专区| 欧美专区日韩视频| 中文字幕日韩精品在线| 亚洲福利视频久久| 91av网站在线播放| 8050国产精品久久久久久| 色婷婷综合久久久久中文字幕1| 中文字幕日韩有码| 欧美日韩免费在线| 91精品在线观看视频| 国产精品久久久久av免费| 亚洲欧美激情另类校园| 中文字幕久热精品视频在线| 亚洲一区二区国产| 欧美成年人视频| 亚洲综合色av| 国产成人精品免高潮费视频| 久久久www成人免费精品张筱雨| 亚洲精品一区中文字幕乱码| 欧美猛交ⅹxxx乱大交视频| 自拍偷拍亚洲在线| 国产成人久久精品| 日韩av日韩在线观看| 国产精品久久77777| 丝袜亚洲另类欧美重口| 在线播放国产一区二区三区| 国产成人精品久久亚洲高清不卡| 日本成人精品在线| 日韩av快播网址| 欧美午夜丰满在线18影院| 91欧美激情另类亚洲| 亚洲欧美国产视频| 国产精品稀缺呦系列在线| 国产精品久久久久久久一区探花| 国产成+人+综合+亚洲欧美丁香花| 国产99久久精品一区二区 夜夜躁日日躁| 亚洲第一黄色网| 亚洲xxxx妇黄裸体| 国产精品久久9| 久久久久久久久久av| 亚洲天堂av在线免费| 国产精品草莓在线免费观看| 国产欧美精品久久久| 亚洲精品国产精品自产a区红杏吧| 亚洲第一av在线| 欧美精品在线观看91| 亚洲自拍另类欧美丝袜| 国产精品视频最多的网站| 7777免费精品视频| 久青草国产97香蕉在线视频| 亚洲影院高清在线| 国产精品三级在线| 少妇精69xxtheporn| 日韩电影免费观看中文字幕| 久99九色视频在线观看| 国产精品美女免费视频| 欧美在线视频在线播放完整版免费观看| 日韩中文在线中文网在线观看| 8x拔播拔播x8国产精品| 68精品国产免费久久久久久婷婷| 日韩欧美国产免费播放| 久久大大胆人体| 日韩欧亚中文在线| 久久香蕉国产线看观看网| 最近2019年好看中文字幕视频| 亚洲精品视频播放| 91国产视频在线播放| 亚洲欧美综合v| 成人高清视频观看www| 欧美成人免费全部| 国产精品香蕉在线观看| 成人a视频在线观看| 中文字幕欧美日韩在线| 日韩精品极品毛片系列视频| 国产成人午夜视频网址| 欧美电影免费观看高清| 国产精品狼人色视频一区| 精品中文字幕久久久久久| 欧美在线一级va免费观看| 欧美亚洲第一区|