场景
我们在做地图引擎的时候,会经常扩展一些插件,有些插件会动态根据地图渲染时机等做一些计算处理重新渲染等,这时候地图渲染时机如何通知到插件,就可以用到这个发布订阅模式来进行。
定义
发布订阅模式,也称为观察者模式,多个观察者可以实时监听某一个具体对象,常见的就是js里面的事件监听。
实现
先看下引擎代码简单骨架:
class MapEngine {constructor(){//...}/**渲染函数,处理渲染等相关事项 */rander(){//省略其他执行代码...//TODO:渲染执行完毕 可以通知渲染执行完成}}export default MapEngine
在TODO的位置可以通知相关插件地图引擎已经执行渲染完成。
这时候我们需要在构造函数里面定义一个订阅数组队列,用来存储要触发的回调函数
/**订阅的渲染处理事件 */this._subscribeRanderEvent = []
增加订阅方法和移除订阅方法
subscribeRander(callback) {const subEnevtId = `生成唯一id`this._subscribeRanderEvent[subEnevtId] = callbackreturn {id: subEnevtId}}unSubscribeRander(id) {delete this._subscribeRanderEvent[id]}
需要订阅的插件直接执行subscribeRander 订阅,这时候在rander里面检查订阅数组并执行相应回调即可
rander(){//省略其他执行代码...//TODO:渲染执行完毕 可以通知渲染执行完成for (const key in this._subscribeRanderEvent) {if (Object.hasOwnProperty.call(this._subscribeRanderEvent, key)) {const callback = this._subscribeRanderEvent[key]if (typeof callback === 'function') callback(_camera)}}}
总结
利用发布订阅模式,可以很方便的扩展引擎类的插件,也很大程度上不会影响原有代码和其他模块的功能逻辑,否则如果只是一个简单的callback回调,每次有新功能进来需要用到这个事件的时候都可能要找到原来的回调入口增加代码,久而久之代码维护性扩展性也会变得越来越差。