发布订阅模式
其实24种基本的设计模式中并没有发布订阅模式,它是观察者模式的一个变体。
订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Topic),当发布者(Publisher)发布该事件(Publish topic)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。
例子:猎人工会
1 | /* 猎人工会是调度中心 |
参考:https://blog.csdn.net/hf872914334/article/details/88899326
例子:发布订阅的封装
1 | // global.js |
1 | // a.js |
1 | // b.js |
1 |
|
点击count button,相当与发布了一个add消息,然后在b.js中订阅add消息的函数就会被调度中心执行。因此如果想要count button取消对add消息的订阅,只需要在调度中心中remove就好了。
参考:https://www.cnblogs.com/itgezhu/p/10947405.html
例子:jquery中的发布订阅
需求:我(订阅者)后天结婚,规划了3件事情,需要(发布者)后天点击提交按钮后执行这三件事。
分析:提前写好三个方法,未来某段时间触发三个方法。
1 | let $pond1 = $.Callbacks();//创建一个事件池 |
关于$.Callbacks()的具体使用,可以参考:https://segmentfault.com/a/1190000004331027
这里面详细讲解了$.Callbacks()实例的各个方法:add(), fire(), fireWith(), empty(), has(), remove(), disable()等。
参考:https://www.jianshu.com/p/d755909b85f8
发布订阅需要考虑的点
- 订阅处理
订阅者可以在消息通道中订阅或者取消订阅某个话题。
- 安全
连接到任何消息通道必须受到安全策略的限制,以防止未经授权的用户或应用程序窃听。
- 内容筛选
根据每条消息的内容检查和分发消息。每个订户都可以指定其感兴趣的内容。
订阅者通常只对发布者分发的消息的子集感兴趣。消息服务通常允许订户缩小以下用户接收到的消息集。
考虑允许订户通过通配符订阅多个主题。每个主题都有一个专用的输出通道,每个使用者都可以订阅所有相关主题。
- 双向通信
发布订阅系统中的通道被视为单向的。
如果特定订户需要向发布服务器发送确认或通信状态,请考虑使用请求/回复模式。此模式使用一个通道向订阅服务器发送消息,以及一个单独的回复通道向发布服务器进行通信。
- 消息排序
使用者实例接收消息的顺序不一定得到保证,也不一定反映消息的创建顺序。
设计该系统以确保消息处理是等量的,以帮助消除对消息处理顺序的任何依赖。
- 消息优先级
有些解决方案可能需要按特定顺序处理消息。优先级队列模式提供了一种确保特定消息先于其他消息传递的机制。
- 有毒信息
格式错误的消息或需要访问不可用资源的任务可能会导致服务实例失败。系统应防止此类消息返回到队列,否则可能导致系统故障。
- 消息重复
同一消息可能会发送多次。例如,发送者可能在发布消息后出现了异常,没有记录自己已经成功发送了消息,然后,发送者的新实例可能会启动并重复该消息。
消息基础结构应基于消息ID实现重复消息检测和删除(也称为重复数据消除),以便最多提供一次消息传递。
- 消息过期
消息的生命周期可能有限。如果在这段时间内没有处理,它可能不再有价值,应该丢弃。发送方可以指定过期时间作为消息中数据的一部分。在决定是否执行与消息关联的业务逻辑之前,接收者可以检查此信息,以确保消息没有过期。
- 消息调度
例如,消息可能会被暂时禁止,直到特定的日期和时间才被处理。