Javascript设计模式 -- 观察者模式

270 阅读1分钟

观察者模式(Observer):又被称为发布-订阅者模式。

DOM事件

DOM事件绑定就是最常见的发布-订阅模式

document.body.addEventListener('click', function(){
    console.log('body1')
})
document.body.addEventListener('click', function(){
    console.log('body2')
})
document.body.click(); //模拟用户点击

我们订阅了body的点击事件,当body被点击时,就会向订阅者发布这个消息

观察者模式的通用实现

在设计观察者对象的时候我们需要注意以下几个点:

  • 有一个消息容器
  • 三个方法:订阅消息方法、发送订阅消息的方法、取消订阅消息的的方法
const Observer = (function() {
  // 存储消息
  const messages = {};
  return {
    // 注册信息
    regist(type, fn) {
      let message = messages[type];
      if (!message) {
        messages[type] = [fn];
      } else {
        messages[type].push(fn);
      }
    },
    // 发布信息
    fire(type, args) {
      let message = messages[type];
      if (!message) {
        return;
      }
      for (let i = 0; i < message.length; i++) {
        message[i].call(this, {
          type: type,
          args: args,
        });
      }
    },
    // 删除信息
    remove(type, fn) {
      let message = messages[type];
      if (message) {
        let ind = message.indexOf(fn);
        if (ind > -1) {
          message.splice(ind, 1);
        }
      }
    },
  };
})();
/*测试*/
Observer.regist('test',function(e){
  console.log(e.type); //注册的类型
  console.log(e.arg);  //发布的参数
})
Observer.fire('test',{msg:'参数'})

上面我们已经实现了观察者对象的基本功能,下面我们思考下面2个问题。

  • 必须先订阅再发布吗?
  • 全局事件的命名冲突

Vue中的观察者模式

双向数据 。。。待整理

小结

观察者模式的优点非常明显,一为时间上的解耦,二为对象之间的解耦。它的应用非常广泛,既可以用在异步编程中,也可以帮助我们完成更松耦合的代码编写。

创建订阅者本身要消耗一定的时间和内存,而且当你订阅一个消息后,也许此消息最后都未发生,但这个订阅者会始终存在于内存中。