摘要:發布者注冊發布訂閱者自動打印消息消息觀察者模式與發布訂閱模式類似。在此種模式中,一個目標物件在它本身的狀態改變時主動發出通知,觀察者收到通知從而使他們的狀態自動發生變化。
做為非科班出身的前端er,每次聽到設計模式都感覺很高大上,總感覺這些東西是造火箭原子彈用的,距離我們這些造螺絲釘很遙遠。但是最近在做一個聊天消息的業務時,發現貌似用上發布訂閱模式業務就很清晰了。創建一個消息類當作發布者,展示消息的函數是訂閱者,發布者提供了注冊、發布方法,訂閱者注冊后,每次調用發布方法修改數據時,訂閱者函數自動更新數據。
class MsgList{//發布者 constructor (){ this.list = []; this.fn = [] } listen(fn){//注冊 this.fn.push(fn) } add(text){//發布 this.list.push(text) this.fn.map((item)=>{ item(this.list) }) } } function show(msg){//訂閱者 console.log(msg) //自動打印 } var msg1 = new MsgList(); msg1.listen(show) msg1.add("消息1") msg1.add("消息2")
觀察者模式與發布訂閱模式類似。在此種模式中,一個目標物件在它本身的狀態改變時主動發出通知,觀察者收到通知從而使他們的狀態自動發生變化。核心就是我(觀察者)正在看著你(被觀察者),看著你目不轉睛...你只要改變我就自動改變。概念是不是很清晰了。但是觀察者模式又跟發布訂閱有些許不太一樣的地方。
一、觀察者模式目標和觀察者是基類,目標提供維護觀察者的一系列方法,觀察者提供更新接口。具體觀察者和具體目標繼承各自的基類,然后具體觀察者把自己注冊到具體目標里,在具體目標發生變化時候,調度觀察者的更新方法。
下面通過js來實現下觀察者模式。首先是目標的構造函數,他有個數組,用于添加觀察者。還有個廣播方法,遍歷觀察者數組后調用他們的update方法:
class Subject{//目標類===被觀察者 constructor(){ this.subjectList = [];//目標列表 } add(fn){//注冊 this.subjectList.push(fn) } notify(context){//發通知 var subjectCount = this.subjectList.length for(var i=0; i < subjectCount; i++){ this.subjectList[i].update(context) } } //取消注冊 remove(fn){ this.subjectList.splice(this.subjectList.indexOf(fn),1) } } class Observer{//觀察者類==觀察者 update(data){ console.log("updata +" + data) } } var Subject1 = new Subject()//具體目標1 var Subject2 = new Subject()//具體目標2 var Observer1 = new Observer()//具體觀察者1 var Observer2 = new Observer()//具體觀察者2 Subject1.add(Observer1);//注冊 //updata +test1 Subject1.add(Observer2);//注冊 //updata +test1 Subject2.add(Observer1);//注冊 //updata +test2 Subject1.notify("test1")//發布事件 Subject2.notify("test2")//發布事件
從上面代碼可以看出來,先創建具體目標和具體觀察者,然后通過add方法把具體觀察者 Observer1、Observer2注冊到具體目標中,目標和觀察者是直接聯系起來的,所以具體觀察者需要提供update方法。在Subject1中發通知時,Observer1、Observer2都會接收通知從而更改狀態。
二、 發布/訂閱模式觀察者模式存在一個問題,目標無法選擇自己想要的消息發布,觀察者會接收所有消息。在此基礎上,出現了
發布/訂閱模式,在目標和觀察者之間增加一個調度中心。訂閱者(觀察者)把自己想訂閱的事件注冊到調度中心,當該事件觸發時候,發布者(目標)發布該事件到調度中心,由調度中心統一調度訂閱者注冊到調度中心的處理代碼。
class Public{//事件通道 constructor(){ this.handlers = {}; } on(eventType, handler) { // 訂閱事件 var self = this; if (!(eventType in self.handlers)) { self.handlers[eventType] = []; } self.handlers[eventType].push(handler); return self ; } emit(eventType) { // 發布事件 var self = this; var handlerArgs = Array.prototype.slice.call(arguments, 1); var length = self.handlers[eventType].length for (var i = 0; i < length; i++) { self.handlers[eventType][i].apply(self, handlerArgs); } return self; } off(eventType, handler) { // 刪除訂閱事件 var currentEvent = this.handlers[eventType]; var len = 0; if (currentEvent) { len = currentEvent.length; for (var i = len - 1; i >= 0; i--) { if (currentEvent[i] === handler) { currentEvent.splice(i, 1); } } } return self ; } } //訂閱者 function Observer1(data) { console.log("訂閱者1訂閱了:" + data) } function Observer2(data) { console.log("訂閱者2訂閱了:" + data) } var publisher = new Public(); //訂閱事件 publisher.on("a", Observer1); publisher.on("b", Observer1); publisher.on("a", Observer2); //發布事件 publisher.emit("a", "第一次發布的a事件"); publisher.emit("b", "第一次發布的b事件"); publisher.emit("a", "第二次發布的a事件"); //訂閱者1訂閱了:第一次發布a事件 //訂閱者2訂閱了:第一次發布a事件 //訂閱者1訂閱了:第一次發布b事件 //訂閱者1訂閱了:第二次發布a事件 //訂閱者2訂閱了:第二次發布a事件
可以看出來,訂閱/發布模式下:訂閱和發布是不直接調度的,而是通過調度中心來完成的,訂閱者和發布者是互相不知道對方的,完全不存在耦合。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105790.html
摘要:姓名小強正式上班時間前端大大強訂閱了這個消息姓名大大強正式上班時間發布者發布消息前端小強姓名小強正式上班時間大大強姓名大大強正式上班時間通過添加了一個,我們實現了對職位的判斷。 觀察者模式,定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都將得到通知。 事實上,只要你曾經在DOM節點上綁定過事件函數,那么你就曾經使用過觀察者模式了! document.b...
摘要:列舉一個生活中的例子來幫助大家理解這一種模式。例子中的小明就是訂閱者訂閱的是飯涼了,而媽媽則是發布者將信號飯涼了發布出去。這樣就不用把小明和媽媽強耦合在一起,當小明的弟弟妹妹都想在飯涼了在吃飯,只需告訴媽媽一聲。 關于事件 在我們使用javascript開發時,我們會經常用到很多事件,如點擊、鍵盤、鼠標等等,這些物理性的事件。而我們今天所說的我稱之為事件的,是另一種形式的事件,訂閱--...
摘要:的異步完成整個異步環節的有事件循環觀察者請求對象以及線程池。執行回調組裝好請求對象送入線程池等待執行,實際上是完成了異步的第一部分,回調通知是第二部分。異步編程是首個將異步大規模帶到應用層面的平臺。 showImg(https://segmentfault.com/img/remote/1460000011303472); 本文首發在個人博客:http://muyunyun.cn/po...
摘要:盡管特定環境下有各種各樣的設計模式,開發者還是傾向于使用一些習慣性的模式。原型設計模式依賴于原型繼承原型模式主要用于為高性能環境創建對象。對于一個新創建的對象,它將保持構造器初始化的狀態。這樣做主要是為了避免訂閱者和發布者之間的依賴。 2016-10-07 每個JS開發者都力求寫出可維護、復用性和可讀性高的代碼。隨著應用不斷擴大,代碼組織的合理性也越來越重要。設計模式為特定環境下的常見...
閱讀 2632·2021-10-14 09:47
閱讀 4909·2021-09-22 15:52
閱讀 3355·2019-08-30 15:53
閱讀 1428·2019-08-30 15:44
閱讀 669·2019-08-29 16:41
閱讀 1646·2019-08-29 16:28
閱讀 439·2019-08-29 15:23
閱讀 1618·2019-08-26 12:20