前言
在之前两篇自测清单中,和大家分享了很多 JavaScript 基础知识,大家可以一起再回顾下~
本文是我在我们团队内部“现代 JavaScript 突击队”分享的一篇内容,第二期学习内容为“设计模式”系列,我会将我负责分享的知识整理成文章输出,希望能够和大家一起温故知新!
“现代 JavaScript 突击队”学习总结:
- 《初中级前端 JavaScript 自测清单 - 1》
- 《初中级前端 JavaScript 自测清单 - 2》
- 《TypeScript 设计模式之观察者模式》
- 《TypeScript语法总结+项目(Vue.js+TS)实战》
一、模式介绍
1. 生活场景
最近刚毕业的学生 Leo 准备开始租房了,他来到房产中介,跟中介描述了自己的租房需求,开开心心回家了。第二天,中介的小哥哥小姐姐为 Leo 列出符他需求的房间,并打电话约他一起看房了,最后 Leo 选中一套满意的房间,高高兴兴过去签合同,准备开始新生活~
还有个大佬 Paul,准备将手中 10 套房出租出去,于是他来到房产中介,在中介那边提供了自己要出租的房间信息,沟通好手续费,开开心心回家了。第二天,Paul 接到中介的好消息,房子租出去了,于是他高高兴兴过去签合同,开始收房租了~
上面场景有个需要特别注意的地方:
- 租户在租房过程中,不知道房间具体房东是谁,到后面签合同才知道;
- 房东在出租过程中,不知道房间具体租户是谁,到后面签合同才知道;
这两点其实就是后面要介绍的 发布-订阅模式 的一个核心特点。
2. 概念介绍
在软件架构中,发布-订阅模式是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。
发布-订阅是消息队列范式的兄弟,通常是更大的面向消息中间件系统的一部分。大多数消息系统在API中同时支持消息队列模型和发布/订阅模型,例如Java消息服务(JMS)。
这种模式提供了更大的网络可扩展性和更动态的网络拓扑,同时也降低了对发布者和发布数据的结构修改的灵活性。
二、 观察者模式 vs 发布-订阅模式
看完上面概念,有没有觉得与观察者模式很像? 但其实两者还是有差异的,接下来一起看看。
1. 概念对比
我们分别为通过两种实际生活场景来介绍这两种模式:
- 观察者模式:如微信中 顾客-微商 关系;
- 发布-订阅模式:如淘宝购物中 顾客-淘宝-商家 关系。
这两种场景的过程分别是这样:
1.1 观察者模式
1.2 发布-订阅模式
接下来看看 发布-订阅模式 :
2. 流程对比
3. 小结
所以可以看出,观察者模式和发布-订阅模式差别在于有没有一个中央的事件总线。如果有,我们就可以认为这是个发布-订阅模式。如果没有,那么就可以认为是观察者模式。因为其实它们都实现了一个关键的功能:发布事件-订阅事件并触发事件。
三、模式特点
对比完观察者模式和发布-订阅模式后,我们大致理解发布-订阅模式是什么了。接着总结下该模式的特点:
1. 模式组成
在发布-订阅模式中,通常包含以下角色:
- 发布者:Publisher
- 事件总线:Event Channel
- 订阅者:Subscriber
2. UML 类图
3. 优点
- 松耦合(Independence)
发布-订阅模式可以将众多需要通信的子系统(Subsystem)解耦,每个子系统独立管理。而且即使部分子系统取消订阅,也不会影响事件总线的整体管理。 发布-订阅模式中每个应用程序都可以专注于其核心功能,而事件总线负责将消息路由到每个订阅者手里。
- 高伸缩性(Scalability)
发布-订阅模式增加了系统的可伸缩性,提高了发布者的响应能力。原因是发布者(Publisher)可以快速地向输入通道发送一条消息,然后返回到其核心处理职责,而不必等待子系统处理完成。然后事件总线负责确保把消息传递到每个订阅者(Subscriber)手里。
- 高可靠性(Reliability)
发布-订阅模式提高了可靠性。异步的消息传递有助于应用程序在增加的负载下继续平稳运行,并且可以更有效地处理间歇性故障。
- 灵活性(Flexibility)
你不需要关心不同的组件是如何组合在一起的,只要他们共同遵守一份协议即可。 发布-订阅模式允许延迟处理或者按计划的处理。例如当系统负载大的时候,订阅者可以等到非高峰时间才接收消息,或者根据特定的计划处理消息。
4. 缺点
- 在创建订阅者本身会消耗内存,但当订阅消息后,没有进行发布,而订阅者会一直保存在内存中,占用内存;
- 创建订阅者需要消耗一定的时间和内存。如果过度使用的话,反而使代码不好理解及代码不好维护。
四、使用场景
如果我们项目中很少使用到订阅者,或者与子系统实时交互较少,则不适合 发布-订阅模式 。 在以下情况下可以考虑使用此模式:
- 应用程序需要向大量消费者广播信息。例如微信订阅号就是一个消费者量庞大的广播平台。
- 应用程序需要与一个或多个独立开发的应用程序或服务通信,这些应用程序或服务可能使用不同的平台、编程语言和通信协议。
- 应用程序可以向消费者发送信息,而不需要消费者的实时响应。