js 设计模式——订阅-发布模式
定义
订阅-发布模式定义了对象之间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都可以得到通知。
与观察者模式的区别
订阅-发布模式与观察者模式概念相似,但在订阅-发布模式中,订阅者与发布者之间多了一层中间件:一个被抽象出来的信息调度中心。
特点
松耦合:订阅者可以订阅多个类型的消息,发布者不需要关心有多少订阅者。
例子
实现一个类似公众号发布文章,取消关注,关注公众号的功能
class Event{ constructor(){ // 收集订阅信息,调度中心 this.list = {}; } // 订阅 subscribe(name,userId,fn){ if(!(this.list[name] instanceof Array)){ this.list[name] = []; } this.list[name].push({userId,fn}); } // 发布 publish(name,content){ this.list[name].forEach(item=>{ item.fn(content); }); } // 取消订阅 removeSub(name,userId){ this.list[name].forEach((item,index)=>{ if(item.userId === userId){ this.list[name].splice(index,1); } }); } } let event = new Event(); //A关注人民日报公众号 event.subscribe('人民日报','A',function(content){ console.log('A接收到人民日报推送的消息',content); }); //B关注湖北日报公众号 event.subscribe('湖北日报','B',function(content){ console.log('B接收到湖北日报推送的消息',content); }); //C关注人民日报公众号 event.subscribe('人民日报','C',function(content){ console.log('C接收到人民日报推送的消息',content); }); // event.publish('人民日报','最高礼遇!以国之名,致敬!'); event.publish('湖北日报','教育部明确!2021年起免试认定!'); event.removeSub('人民日报','A'); event.publish('人民日报',"严防不懈!新增确诊2例,均为境外输入");
每次订阅会将订阅者的信息存与调度中心(event实例的list)中,当发布信息时(如人民日报发送新闻),会从list中取出相关发布的信息数组(人民日报的订阅者数组)进行遍历执行回调函数。
输出结果如下:
优缺点
优点
- 对象之间解耦
- 异步编程中,可以更松耦合的代码编写
缺点
- 创建订阅者本身要消耗一定的时间和内存
- 虽然可以弱化对象之间的联系,但多个发布者和订阅者嵌套在一起时,程序会变的难以跟踪维护。