发布订阅模式理解

article/2025/10/27 0:26:22

发布订阅模式理解

1.发布-订阅模式

发布订阅模式是一种一对多的对象对应关系,多个观察者同时监听某一个对象,当该对象发生改变时,就会执行一个发布事件,这个发布事件会通知所有的事件订阅者,事件订阅者根据得到的数据进而改变自己的状态。
一个完整的发布订阅模式,由发布者、订阅者和消息管理器组成。
在这里插入图片描述
2.发布订阅模式的实现思路

1)创建一个发布者对象,并在其上添加一个列表属性,用于存放订阅者的回调函数
2)发布者发布消息,将消息依次传给每一个列表中的回调函数并触发它

简单的demo:

var shoeObj = {//存放订阅者的回调函数list:[],//将订阅者的回调函数放在列表中listen(){shoeObj.list.push(fn);},//发布消息trigger(){for(var i = 0,fn; fn = this.list[i++];) {//将参数应用于每一个回调函数fn.apply(this,arguments); }}
}; 
//小红的订阅数据
shoeObj.listen(function(color,size){console.log("颜色是:"+color);console.log("大小是:"+size);
})
//小明的订阅数据
shoeObj.listen(function(color,size){console.log(123,color,size);
})
//发布数据
shoeObj.trigger("红色",40);
shoeObj.trigger("黑色",42);

输出结果:
在这里插入图片描述
增加key:让用户只接收自己感兴趣的信息

var shoeObj = {//存放订阅者的回调函数list:[],//将订阅者的回调函数放在列表中listen(key,fn){//为每一个key创建一个列表if (!this.list[key]){this.list[key]=[];}shoeObj.list[key].push(fn);},//发布消息,将信息发布给每一个回调函数trigger(){var key = Array.prototype.shift.call(arguments); // 取出消息类型名称var fns = this.list[key];  // 取出该key对应的回调函数的集合// 如果没有订阅过该消息的话,则返回if(!fns || fns.length === 0) {return;}for(var i = 0,fn; fn = fns[i++];) {//将参数应用于每一个回调函数fn.apply(this,arguments); }}}; //小红的订阅数据,key是‘red’shoeObj.listen('red',function(size){console.log("大小是:"+size);})//小明的订阅数据,key是‘black’shoeObj.listen('black',function(size){console.log(123,size);})//发布消息shoeObj.trigger("red",40);shoeObj.trigger("black",42);

输出结果:在这里插入图片描述
这样,订阅者就只订阅了自己感兴趣的信息了。

将代码进行封装,可以应用于各种场景:

var event = {//存放订阅者的回调函数list:[],//将订阅者的回调函数放在列表中listen(key,fn){//为每一个key创建一个列表if (!this.list[key]){this.list[key]=[];}this.list[key].push(fn);},//发布消息,将信息发布给每一个回调函数trigger(){var key = Array.prototype.shift.call(arguments); // 取出消息类型名称var fns = this.list[key];  // 取出该key对应的回调函数的集合// 如果没有订阅过该消息的话,则返回if(!fns || fns.length === 0) {return;}for(var i = 0,fn; fn = fns[i++];) {//将参数应用于每一个回调函数fn.apply(this,arguments); }}}; //初始化普通对象,使其具有发布订阅功能var initEvent = function(obj) {for(var i in event) {obj[i] = event[i];}};

加入取消订阅:

var event = {//存放订阅者的回调函数list:[],//将订阅者的回调函数放在列表中listen(key,fn){//为每一个key创建一个列表if (!this.list[key]){this.list[key]=[];}this.list[key].push(fn);},//发布消息,将信息发布给每一个回调函数trigger(){var key = Array.prototype.shift.call(arguments); // 取出消息类型名称var fns = this.list[key];  // 取出该key对应的回调函数的集合// 如果没有订阅过该消息的话,则返回if(!fns || fns.length === 0) {return;}for(var i = 0,fn; fn = fns[i++];) {//将参数应用于每一个回调函数fn.apply(this,arguments); }},//取消订阅remove(key,fn){var fns = this.list[key];// 如果key对应的消息没有订阅过的话,则返回if(!fns) {return false;}// 如果没有传入具体的回调函数,表示需要取消key对应消息的所有订阅if(!fn) {fn && (fns.length = 0);}else {for(var i = fns.length - 1; i >= 0; i--) {var _fn = fns[i];if(_fn === fn) {fns.splice(i,1); // 删除订阅者的回调函数}}}}}; //初始化普通对象,使其具有发布订阅功能var initEvent = function(obj) {for(var i in event) {obj[i] = event[i];}};

封装发布订阅模式:

//发布订阅模式
class eventEmitter(){constructor(){this.list = {};}listen(key,fn){if(!this.list[key]){this.list[key] = [];}this.list[key].push(fn);}publish(){let key = Array.prototype.shift.call(arguments);let fns = this.list[key];if (!fns||fns.length===0){return ;}for(let i=0;i<fns.length;i++){fns[i].apply(this,arguments);}}remove(key,fn){let fns = this.list[key];if (!fns || fns.length === 0){return ;}if (!fn){this.list[key]=[];} else {let fnsFilter = fns.filter((it,ind)=>{return it != fn;})this.list[key]=fnsFilter;}}}
export default new eventEmitter();

3.为什么要用发布订阅模式?
如果一个数据或者事件的变化会对很多事件产生影响,比如我们在初始化接口之后会得到初始化数据,当初始化接口返回成功时,需要执行其他的几个方法,正常情况下,我们会注册一个函数,在这个函数中写n个函数的执行,但是如果利用发布订阅模式,其他几个函数可以订阅该接口的成功事件,然后根据订阅接收到的数据执行自己的函数。
优点:耦合性低,便于代码的维护

参考博客:https://www.cnblogs.com/itgezhu/p/10947405.html


http://chatgpt.dhexx.cn/article/3RsoqmVb.shtml

相关文章

JS观察者模式和发布订阅模式

观察者模式 观察者模式在前端工程中是很常见的设计模式&#xff0c;因为前端交互中充斥着大量多控件联动的交互&#xff0c;当参与联动的组件数量比较多或者组件数量可能变化的时候&#xff0c;代码就会变得难以维护。但是如果我们写代码时遵循了观察者模式的设计&#xff0c;…

redis发布订阅模式详解

文章目录 写在前面发布订阅的使用SUBSCRIBE命令PUBLISH命令注意发布、订阅客户端启动顺序&#xff01; PUBSUB命令PUNSUBSCRIBE命令UNSUBSCRIBE命令PSUBSCRIBE命令 总结 写在前面 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订…

Vue发布订阅模式

简单的来说一下在别人问你这个问题的时候怎么来回答它 前端新人&#xff0c;如有错误求大佬指出~求教&#x1f49d; 情景复现 大佬提问&#xff1a;“你知道Vue发布订阅模式是什么吗&#xff1f;" 我的回答&#xff1a;“发布订阅模式其实是一种对象间一对多的依赖关系&…

观察者模式和发布订阅模式

一、概念 观察者(Observer)&#xff0c;又称发布-订阅&#xff08;Publish-Subscrice&#xff09;&#xff0c;属于23中设计模式之一。 发布订阅模式定义了一种一对多的依赖关系&#xff0c;让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时&#xff0c…

C++发布订阅模式

C发布订阅模式 发布订阅模式主要包含三个部分&#xff1a;消息发布、消息订阅者、消息处理中心。与观察者模式相比多出了消息处理中心模块&#xff0c;这样在结构上可以解耦订阅者与发布者&#xff0c;功能上更加的丰富。 观察者模式 结构设计 有一个消息list&#xff0c;主…

Java实现发布订阅模式

什么是发布订阅模式 发布订阅模式是软件开发者很常见的一种设计模式&#xff0c;很多开源库都使用了发布订阅模式&#xff0c;例如RxJava、EventBus、Vue等&#xff0c;所以学习该模式还是很有必要的。 该模式中存在一个或多个发布者&#xff0c;一个或多个订阅者&#xff0c…

设计模式 —— 发布订阅模式

设计模式 —— 发布订阅模式 《工欲善其事&#xff0c;必先利其器》 我在之前有写过一篇关于 《观察者模式》 的文章&#xff0c;大家有兴趣的可以去看看&#xff0c;个人认为那个例子还是挺生动的。&#xff08;狗头&#xff09; 不过今天我们要学习的是&#xff0c;发布订阅…

小侃设计模式(十八)-发布订阅模式

1.概述 发布订阅模式又叫观察者模式&#xff08;Observer Pattern&#xff09;&#xff0c;它是指对象之间一对多的依赖关系&#xff0c;每当那个特定对象改变状态时&#xff0c;所有依赖于它的对象都会得到通知并被自动更新&#xff0c;它是行为型模式的一种。观察者模式内部…

发布-订阅模式

发布-订阅模式 学习知识要善于思考&#xff0c;思考&#xff0c;再思考。 —— 爱因斯在众多设计模式中&#xff0c;可能最常见、最有名的就是发布 - 订阅模式了&#xff0c;本篇我们一起来学习这个模式。 发布 - 订阅模式 &#xff08;Publish-Subscribe Pattern, pub-sub&a…

什么是发布订阅模式?

发布-订阅模式&#xff08;Publish-Subscribe pattern&#xff09;是一种软件架构模式&#xff0c;用于实现组件之间的解耦和消息传递。在这种模式中&#xff0c;组件&#xff08;发布者&#xff09;将消息发送到一个中心&#xff08;消息代理或主题&#xff09;&#xff0c;然…

发布订阅模式

零、目录 应用场景实现原理代码实现全局模式下的订阅发布模式&#xff08;泛化的订阅发布模式&#xff09;总结 一、应用场景 ​ 发布订阅模式&#xff0c;广泛的存在于在我们的生活之中。 ​ 举个一个简单的例子来说&#xff0c;当我们在浏览视频或者博客论坛之类的网…

.NET(C#、VB)APP开发——Smobiler平台控件介绍:VLCPlayer

本文简述如何在Smobiler中使用VLCPlayer插件&#xff0c;该插件支持播放rtsp流。 Step 1. 新建一个SmobilerForm窗体&#xff0c;再拖入VLCPlay&#xff0c;布局如下 在设计器中给VLCPlayer.Url赋值或者在窗体的Load事件中赋值 演示使用的rtsp流地址 rtsp://wowzaec2demo.strea…

.NET(C#、VB)APP开发——Smobiler平台控件介绍:TTS

本文简述如何在Smobiler中使用TTS文字转语音。 Step 1. 新建一个SmobilerForm窗体&#xff0c;并在窗体中加入TTS和Button&#xff0c;布局如下 Button的点击事件代码&#xff1a; private void button1_Press(object sender, EventArgs e){ //第一个参数为文本&#xff1b;第…

Smobiler 仿得到APP个人主页

原型如下&#xff1a; 完整代码参考 https://github.com/comsmobiler/BlogsCode/blob/master/Source/BlogsCode_SmobilerForm/MyForm/dedao.cs 思路 可以将原型按照上图分成2个部分&#xff0c;部分A可以使用label、image、button、imagebutton、fontIcon控件来实现&#xff…

.NET(C#、VB)APP开发——Smobiler平台控件介绍:PDFView

本文简述如何在Smobiler中使用PDFView。 Step 1. 新建一个SmobilerForm窗体&#xff0c;再拖入PDfView&#xff0c;布局如下 PDFView.ResourcrPath默认Document&#xff0c;指项目下\Resources\Document&#xff0c;若是pdf文件放在该文件夹下&#xff0c;则在设计器中直接赋值…

.NET(C#、VB)APP开发——Smobiler平台控件介绍:OCR组件

本文简述如何在Smobiler中使用OCR组件进行文字识别。 Step 1. 新建一个SmobilerForm窗体&#xff0c;并在窗体中加入OCR和Button&#xff0c;布局如下 Button的点击事件代码&#xff1a; private void button1_Press(object sender, EventArgs e){ocr1.Recognize((obj,args)>…

.NET(C#、VB)APP开发——Smobiler平台控件介绍:ArcFace人脸识别

本文简述如何在Smobiler中使用ArcFace&#xff08;虹软人脸识别&#xff09;。 Step 1. 新建一个SmobilerForm窗体&#xff0c;再拖入Button,Label,TextBox和AcrFace,布局如下 在设计器中给MediaView.Url赋值或者在窗体的Load事件中赋值 Button的事件代码如下 string message …

移动OA办公——Smobiler第一个开源应用解决方案,快来get吧

产品简介 SmoONE是一款移动OA类的开源解决方案&#xff0c;通过Smobiler平台开发&#xff0c;包含了注册、登陆、用户信息等基本功能。集成了OA中使用场景较多的报销、请假、部门管理、成本中心等核心功能。 免费获取方案 开源代码&#xff1a;https://github.com/comsmobile…

.NET(C#、VB)APP开发——Smobiler平台控件介绍:UsbSerial串口通讯组件

本文简述如何在Smobiler中使用UsbSerial。 Step 1. 新建一个SmobilerForm窗体&#xff0c;再拖入UsbSerial和Button&#xff0c;布局如下 按钮事件代码&#xff1a; //连接private void button1_Press_2(object sender, EventArgs e){usbSerial1.Connect(Smobiler.Plugins.USBS…

Smobiler实现手机弹窗

前言 在实际项目中有很多场景需要用到弹窗&#xff0c;如图1 那么这些弹窗在Smobiler中如何实现呢&#xff1f; 正文 Smobiler实现弹窗有两种方式&#xff1a;1.MessageBox.Show 2.ShowDialog和ShowContextDialog。前者适合简易弹窗&#xff0c;后者适合自定义弹窗。 Messa…