被考察很多次的发布订阅模式

4 个月前(已编辑)
12
这篇文章上次修改于 4 个月前,可能部分内容已经不适用,如有疑问可询问作者。

在观察大佬们的面经时,常常提起“发布订阅模式”、“手写 EventEmitter”,遂学习,记录于此,对这篇文章有大量(搬运)参考

介绍

发布订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到状态改变的通知。

发布订阅模式中,包含发布者,事件调度中心,订阅者三个角色。发布者和订阅者是松散耦合的,互不关心对方是否存在,他们关注的是事件本身。发布者借用事件调度中心提供的publish方法发布事件,而订阅者则通过subscribe进行订阅。

特点

  • 发布订阅模式中,对于发布者Publisher和订阅者Subscriber没有特殊的约束,他们好似是匿名活动,借助事件调度中心提供的接口发布和订阅事件,互不了解对方是谁。
  • 松散耦合,灵活度高,常用作事件总线。
  • 易理解,可类比于DOM事件中的dispatchEventaddEventListener

缺点

  • 当事件类型越来越多时,难以维护,需要考虑事件命名的规范,也要防范数据流混乱。

和观察者模式的区别

定性上:观察者是经典软件设计模式中的一种,但发布订阅只是软件架构中的一种消息范式

组成上:观察者模式本身只需要2个角色便可成型,即观察者被观察者,其中被观察者是重点。而发布订阅需要至少3个角色来组成,包括发布者订阅者发布订阅中心,其中发布订阅中心是重点。

实现上:

观察者模式一般至少有一个可被观察的对象 Subject,可以有多个观察者去观察这个对象。二者的关系是通过被观察者主动建立的,被观察者至少要有三个方法——添加观察者、移除观察者、通知观察者。

当被观察者将某个观察者添加到自己的观察者列表后,观察者与被观察者的关联就建立起来了。此后只要被观察者在某种时机触发通知观察者方法时,观察者即可接收到来自被观察者的消息。

被观察者是要有一个数组来容纳所有的观察者!


与观察者模式相比,发布订阅核心基于一个中心来建立整个体系。其中发布者和订阅者不直接进行通信,而是发布者将要发布的消息交由中心管理,订阅者也是根据自己的情况,按需订阅中心中的消息。

> 关联:发布订阅的实现内部利用了观察者模式订阅者发布订阅中心的关系类似观察者被观察者的关系。

简单实现

手写 EventEmitter

EventEmitter (事件派发器)是 Node.js 的核心模块 events 中的类,用于对 Node.js 中的事件进行统一管理,用 events 特定的 API 对事件进行添加、触发和移除等等,EventEmitter 的核心就是事件触发与事件监听器功能的封装。

简而言之,EventEmitter就是一个典型的发布订阅模式,实现了事件调度中心。

实现:

使用:

评论区加载中...