【设计模式】---观察者模式与发布订阅者模式

2022-10-08  本文已影响0人  DY_alley

一、观察者模式和发布订阅者模式之间的区别

0.png

观察者模式中观察者和目标直接进行交互, 而发布订阅模式由统一的调度中心来进行处理。订阅者和发布者互不干扰。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。观察者是一对多的关系状态

虽然两种模式都存在订阅者和发布者,但是观察者模式是由具体目标调度的,而发布订阅模式是由调度中心调度的。所以观察者模式的订阅者和发布者之间是存在以来的。而发布订阅模式则不会。

(观察者)订阅者和订阅目标是联系在一起的,当订阅目标发生改变时,逐个通知订阅者。我们可以用报纸期刊的订阅来形象的说明,当你订阅了一份报纸,每天都会有一份最新的报纸送到你手上,有多少人订阅报纸,报社就会发多少份报纸,报社和订报纸的客户就是上面文章开头所说的“一对多”的依赖关系。

(发布订阅)举一个例子,你在微博上关注了A,同时其他很多人也关注了A,那么当A发布动态的时候,微博就会为你们推送这条动态。A就是发布者,你是订阅者,微博就是调度中心,你和A是没有直接的消息往来的,全是通过微博来协调的(你的关注,A的发布动态)

二、观察者

class Observer {
  constructor(){}

  update(val){}
}

class ObserverList {
    constructor() {
      this.observerlist = [];
    }

    add(observer) {
     return  this.observerlist.push(observer);
    }

    remove(observer) {
      this.observerlist = this.observerlist.filter(item=>item !== observer);
    }

    count() {
      return this.observerlist.length;
    }

    get(index) {
      return this.observerlist[index];
    }
}

class Subject {
    constructor() {
        this.observers = new ObserverList();
    }
    addObserver(observer) {
      this.observers.add(observer);
    }
    removeObserver(observer) {
      this.observers.remove(observer);
    }
    notify(...arg) {
        let len = this.observers.count();
        for(var i=0;i<len;i++) {
          this.observers.get(i).update(...arg);
        }
    }
}

三、发布订阅

class EventBus { 
  constructor() {
      this.handlers = {};
  }

  $on(type,fn) {
    if(Reflect.has(this.handlers,type)) {
      this.handlers[type] = [];
    }

    this.handlers[type].push(fn);
  }


  $emit(type,...params) {
    if(!Reflect.has(this.handlers,type)) {
      throw new Error('当前事件未注册');
    }

    this.handlers[type].forEach((cb)=>{cb(...params)});
  }

  $off(type,fn) {
    if(!Reflect.has(this.handlers,type)) {
        throw new Error('无效事件');
    }

    if(!fn) {
        return Reflect.deleteProperty(this.handlers,type);
    } else {
        const index = this.handlers[type].findIndex((cb)=>cb === fn);
        if(index === -1) {
            throw new Error('无效事件');
        }

        this.handlers[type].splice(index,1); // 从列表事件中删除

        if(!this.handlers[type].length) { // 如果这个事件列表中没有事件了,则删除该事件
            return Reflect.deleteProperty(this.handlers,type); 
        }
    }
  }
}
上一篇下一篇

猜你喜欢

热点阅读