浅析观察者模式与发布订阅模式

118 阅读2分钟

发布订阅模式

  • 什么是发布订阅模式:订阅好一件事,当这件事发生的时候触发对应的函数。
  • 什么是订阅,什么是发布

       订阅 (on):就是将函数放入数组中,每次发布都会触发此函数;

       发布(emit):让订阅的数组中的方法依次执行。

  • 发布订阅模式的特点和好处:订阅方和发布方没有任何的关系,订阅方往数组中存callback,发布方从数组中取出方法依次执行,他们并不关心彼此,没有订阅也可以发布。发布订阅的核心可以解耦合,订阅和发布可以在两个无关的类里。

实现一个简易的发布订阅模式

const e = {
  _obj = {},
  _callback = [],
  on(callback){
    this._callback.push(callback)
  },
  emit(key,value){
    this._obj[key] =value;
    this._callback.forEach(method=>{
      method(this._obj)
    })
  }
 }
e.on(function(obj){
  console.log(obj); //{age: 18}
});
fs.readFile('./age.text','utf-8',function(error,data){
  e.emit('age',data)
});

观察者模式

内部也是基于发布订阅模式,观察者和被观察者是有关联的,观察者需要将自己放到被观察者之上,当被观察者的状态发生变化,需要通知所有的观察者,vue里面用的是这种模式。

假设有一个小宝宝,当他的心情发生变化后他是如何告知他的父母,下面用一个简单的例子来实现这个观察者模式

//被观察者
class Subject{
   constructor(name){
    this.name = name;
    this.state = "开心";
    this.observer = [];
  }
  attach(o){ //需要将注册者放在自己的身上
    this.observer.push(o); // 相当于发布订阅的on
  }
  setState(state){
    this.state = state; //更新被观察者的状态
    //当状态发生改变后续通知观察者
    this.observer.forEach(o=>{ //相当于发布订阅的emit
      o.update(this);
    })
  }};
//观察者
class Observer{
   constructor(name){
    this.name = name;
  }
  update(s){ //等会被观察者的状态发生变化时会调用这个方法
    console.log(`${this.name}:${s.name}当前的状态是${s.state}`);  //爸爸:小宝宝当前的状态是不开心
  }}
let baby = new Subject("小宝宝");
let father = new Observer("爸爸");
let mother = new Observer("妈妈");
baby.attach(father);baby.attach(mother);
//被观察者的状态发生了变化
baby.setState("不开心");