成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

10分鐘弄懂一種簡(jiǎn)單的js設(shè)計(jì)模式(觀察者/發(fā)布訂閱)

xiguadada / 2054人閱讀

摘要:發(fā)布者注冊(cè)發(fā)布訂閱者自動(dòng)打印消息消息觀察者模式與發(fā)布訂閱模式類(lèi)似。在此種模式中,一個(gè)目標(biāo)物件在它本身的狀態(tài)改變時(shí)主動(dòng)發(fā)出通知,觀察者收到通知從而使他們的狀態(tài)自動(dòng)發(fā)生變化。

做為非科班出身的前端er,每次聽(tīng)到設(shè)計(jì)模式都感覺(jué)很高大上,總感覺(jué)這些東西是造火箭原子彈用的,距離我們這些造螺絲釘很遙遠(yuǎn)。但是最近在做一個(gè)聊天消息的業(yè)務(wù)時(shí),發(fā)現(xiàn)貌似用上發(fā)布訂閱模式業(yè)務(wù)就很清晰了。創(chuàng)建一個(gè)消息類(lèi)當(dāng)作發(fā)布者,展示消息的函數(shù)是訂閱者,發(fā)布者提供了注冊(cè)、發(fā)布方法,訂閱者注冊(cè)后,每次調(diào)用發(fā)布方法修改數(shù)據(jù)時(shí),訂閱者函數(shù)自動(dòng)更新數(shù)據(jù)。

class MsgList{//發(fā)布者
    constructor (){
        this.list = [];
        this.fn = []
    }
    listen(fn){//注冊(cè)
      this.fn.push(fn)
    }
    add(text){//發(fā)布
        this.list.push(text)
        this.fn.map((item)=>{
            item(this.list)
        })
    }
}
function show(msg){//訂閱者
    console.log(msg) //自動(dòng)打印
}
var msg1 = new MsgList();
msg1.listen(show)
msg1.add("消息1")
msg1.add("消息2")

觀察者模式與發(fā)布訂閱模式類(lèi)似。在此種模式中,一個(gè)目標(biāo)物件在它本身的狀態(tài)改變時(shí)主動(dòng)發(fā)出通知,觀察者收到通知從而使他們的狀態(tài)自動(dòng)發(fā)生變化。核心就是我(觀察者)正在看著你(被觀察者),看著你目不轉(zhuǎn)睛...你只要改變我就自動(dòng)改變。概念是不是很清晰了。但是觀察者模式又跟發(fā)布訂閱有些許不太一樣的地方。

一、觀察者模式

目標(biāo)觀察者是基類(lèi),目標(biāo)提供維護(hù)觀察者的一系列方法,觀察者提供更新接口。具體觀察者和具體目標(biāo)繼承各自的基類(lèi),然后具體觀察者把自己注冊(cè)到具體目標(biāo)里,在具體目標(biāo)發(fā)生變化時(shí)候,調(diào)度觀察者的更新方法。

下面通過(guò)js來(lái)實(shí)現(xiàn)下觀察者模式。首先是目標(biāo)的構(gòu)造函數(shù),他有個(gè)數(shù)組,用于添加觀察者。還有個(gè)廣播方法,遍歷觀察者數(shù)組后調(diào)用他們的update方法:

class Subject{//目標(biāo)類(lèi)===被觀察者
    constructor(){
        this.subjectList = [];//目標(biāo)列表
    }
    add(fn){//注冊(cè)
        this.subjectList.push(fn)
    }
    notify(context){//發(fā)通知    
        var subjectCount = this.subjectList.length
        for(var i=0; i < subjectCount; i++){
            this.subjectList[i].update(context)
        }
    }
    //取消注冊(cè)
    remove(fn){
        this.subjectList.splice(this.subjectList.indexOf(fn),1)
    }
}

class Observer{//觀察者類(lèi)==觀察者
    update(data){
        console.log("updata +" + data)
    }
}

var Subject1 = new Subject()//具體目標(biāo)1
var Subject2 = new Subject()//具體目標(biāo)2

var Observer1 = new Observer()//具體觀察者1
var Observer2 = new Observer()//具體觀察者2

Subject1.add(Observer1);//注冊(cè) //updata +test1
Subject1.add(Observer2);//注冊(cè) //updata +test1
Subject2.add(Observer1);//注冊(cè) //updata +test2

Subject1.notify("test1")//發(fā)布事件
Subject2.notify("test2")//發(fā)布事件

從上面代碼可以看出來(lái),先創(chuàng)建具體目標(biāo)具體觀察者,然后通過(guò)add方法把具體觀察者 Observer1、Observer2注冊(cè)到具體目標(biāo)中,目標(biāo)和觀察者是直接聯(lián)系起來(lái)的,所以具體觀察者需要提供update方法。在Subject1中發(fā)通知時(shí),Observer1、Observer2都會(huì)接收通知從而更改狀態(tài)。

二、 發(fā)布/訂閱模式

觀察者模式存在一個(gè)問(wèn)題,目標(biāo)無(wú)法選擇自己想要的消息發(fā)布,觀察者會(huì)接收所有消息。在此基礎(chǔ)上,出現(xiàn)了
發(fā)布/訂閱模式,在目標(biāo)和觀察者之間增加一個(gè)調(diào)度中心。訂閱者(觀察者)把自己想訂閱的事件注冊(cè)到調(diào)度中心,當(dāng)該事件觸發(fā)時(shí)候,發(fā)布者(目標(biāo))發(fā)布該事件到調(diào)度中心,由調(diào)度中心統(tǒng)一調(diào)度訂閱者注冊(cè)到調(diào)度中心的處理代碼。

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) {    // 發(fā)布事件
        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);

//發(fā)布事件
publisher.emit("a", "第一次發(fā)布的a事件");
publisher.emit("b", "第一次發(fā)布的b事件");
publisher.emit("a", "第二次發(fā)布的a事件"); 
//訂閱者1訂閱了:第一次發(fā)布a事件
//訂閱者2訂閱了:第一次發(fā)布a事件
//訂閱者1訂閱了:第一次發(fā)布b事件
//訂閱者1訂閱了:第二次發(fā)布a事件
//訂閱者2訂閱了:第二次發(fā)布a事件

可以看出來(lái),訂閱/發(fā)布模式下:訂閱和發(fā)布是不直接調(diào)度的,而是通過(guò)調(diào)度中心來(lái)完成的,訂閱者和發(fā)布者是互相不知道對(duì)方的,完全不存在耦合。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/105790.html

相關(guān)文章

  • js設(shè)計(jì)模式筆記 - 察者模式

    摘要:姓名小強(qiáng)正式上班時(shí)間前端大大強(qiáng)訂閱了這個(gè)消息姓名大大強(qiáng)正式上班時(shí)間發(fā)布者發(fā)布消息前端小強(qiáng)姓名小強(qiáng)正式上班時(shí)間大大強(qiáng)姓名大大強(qiáng)正式上班時(shí)間通過(guò)添加了一個(gè),我們實(shí)現(xiàn)了對(duì)職位的判斷。 觀察者模式,定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都將得到通知。 事實(shí)上,只要你曾經(jīng)在DOM節(jié)點(diǎn)上綁定過(guò)事件函數(shù),那么你就曾經(jīng)使用過(guò)觀察者模式了! document.b...

    txgcwm 評(píng)論0 收藏0
  • 擼一個(gè)JS事件管理模塊

    摘要:列舉一個(gè)生活中的例子來(lái)幫助大家理解這一種模式。例子中的小明就是訂閱者訂閱的是飯涼了,而媽媽則是發(fā)布者將信號(hào)飯涼了發(fā)布出去。這樣就不用把小明和媽媽強(qiáng)耦合在一起,當(dāng)小明的弟弟妹妹都想在飯涼了在吃飯,只需告訴媽媽一聲。 關(guān)于事件 在我們使用javascript開(kāi)發(fā)時(shí),我們會(huì)經(jīng)常用到很多事件,如點(diǎn)擊、鍵盤(pán)、鼠標(biāo)等等,這些物理性的事件。而我們今天所說(shuō)的我稱(chēng)之為事件的,是另一種形式的事件,訂閱--...

    harryhappy 評(píng)論0 收藏0
  • Node.js 異步異聞錄

    摘要:的異步完成整個(gè)異步環(huán)節(jié)的有事件循環(huán)觀察者請(qǐng)求對(duì)象以及線(xiàn)程池。執(zhí)行回調(diào)組裝好請(qǐng)求對(duì)象送入線(xiàn)程池等待執(zhí)行,實(shí)際上是完成了異步的第一部分,回調(diào)通知是第二部分。異步編程是首個(gè)將異步大規(guī)模帶到應(yīng)用層面的平臺(tái)。 showImg(https://segmentfault.com/img/remote/1460000011303472); 本文首發(fā)在個(gè)人博客:http://muyunyun.cn/po...

    zzbo 評(píng)論0 收藏0
  • [譯] 你應(yīng)了解4種JS設(shè)計(jì)模式

    摘要:盡管特定環(huán)境下有各種各樣的設(shè)計(jì)模式,開(kāi)發(fā)者還是傾向于使用一些習(xí)慣性的模式。原型設(shè)計(jì)模式依賴(lài)于原型繼承原型模式主要用于為高性能環(huán)境創(chuàng)建對(duì)象。對(duì)于一個(gè)新創(chuàng)建的對(duì)象,它將保持構(gòu)造器初始化的狀態(tài)。這樣做主要是為了避免訂閱者和發(fā)布者之間的依賴(lài)。 2016-10-07 每個(gè)JS開(kāi)發(fā)者都力求寫(xiě)出可維護(hù)、復(fù)用性和可讀性高的代碼。隨著應(yīng)用不斷擴(kuò)大,代碼組織的合理性也越來(lái)越重要。設(shè)計(jì)模式為特定環(huán)境下的常見(jiàn)...

    awokezhou 評(píng)論0 收藏0
  • js 察者

    摘要:觀察者模式機(jī)動(dòng)建立一種對(duì)象與對(duì)象之間的依賴(lài)關(guān)系,一個(gè)對(duì)象發(fā)生改變時(shí)將自動(dòng)通知其他對(duì)象,其他對(duì)象將相應(yīng)做出反應(yīng)。 觀察者模式模式簡(jiǎn)介 觀察者模式(又被稱(chēng)為發(fā)布-訂閱(Publish/Subscribe)模式,屬于行為型模式的一種,它定義了一種一對(duì)多的依賴(lài)關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)變化時(shí),會(huì)通知所有的觀察者對(duì)象,使他們能夠自動(dòng)更新自己。 觀察者模式機(jī)動(dòng)...

    missonce 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<