JavaScript设计模式:四、发布订阅模式

2023-05-16

JavaScript设计模式:四、发布订阅模式

文章目录

  • JavaScript设计模式:四、发布订阅模式
    • 一、概述
      • 1. 观察者模式
      • 2. 发布订阅模式
      • 3. 观察者模式是不是发布订阅模式

一、概述

观察者模式: 观察者(Observer)直接订阅(Subscribe)主题(Subject),而当主题被激活的时候,会触发(Fire Event)观察者里的事件。

发布订阅模式: 订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Topic),当发布者(Publisher)发布该事件(Publish topic)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。
在这里插入图片描述

1. 观察者模式

  1. 首先定义一个数组存储订阅列表(数组存函数)
  2. 定义订阅函数,函数参数:订阅对象与订阅信息。函数体负责将订阅信息(为一个函数)存入订阅数组列表。
  3. 定义发布任务函数,函数接受订阅信息参数。函数体内遍历订阅信息,以遍能够找到匹配的订阅信息。

主要维护一个存储函数的数组,通过入栈的方式维护订阅信息,通过数组遍历的方式使用订阅列表,以找到匹配的订阅信息。

function Hunter(name, level) {
  this.name = name;
  this.level = level;
  this.list = [];
}
Hunter.prototype.publish = function(money) {
  console.log(this.level + '猎人' + this.name + '寻求帮助');
  this.list.forEach(function(item, index) {
    item(money);
  })
}
Hunter.prototype.subscribe = function(target, fn) {
  console.log(this.level + '猎人' + this.name + '订阅了' + target);
  target.list.push(fn); // 向目标猎人list中推入订阅
}
let hounterMing = new Hunter('小明','黄金');
let hounterJin = new Hunter('小金','黄金');
let hounterZhang = new Hunter('校长', '黄金');
let hounterPeter = new Hunter('Peter', '黄铜');

hunterMing.subscribe(hunterPeter, function(money){
  console.log('小明表示:' + (money > 200 ? '' : '暂时很忙,不能') + '给予帮助')
})
hunterJin.subscribe(hunterPeter, function(){
  console.log('小金表示:给予帮助')
})
hunterZhang.subscribe(hunterPeter, function(){
  console.log('小金表示:给予帮助')
})
hunterPeter.publish(198)

2. 发布订阅模式

观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心。

观察者模式由具体目标调度,每个被订阅的目标里面都需要有对观察者的处理,这种处理方式比较直接粗暴,但是会造成代码的冗余。

而发布订阅模式中统一由调度中心进行处理,订阅者和发布者互不干扰,消除了发布者和订阅者之间的依赖。这样一方面实现了解耦,还有就是可以实现更细粒度的一些控制。比如发布者发布了很多消息,但是不想所有的订阅者都接收到,就可以在调度中心做一些处理,类似于权限控制之类的。还可以做一些节流操作。

通俗版本:

  1. 发布订阅模式就是将原本属于被订阅者维护的订阅列表独立出来,增加了一个专门处理订阅信息的订阅中心。实际上依然是维护一个数组列表。
  2. 发布者和订阅者的发布和订阅的具体内部逻辑被订阅中心接管,只需要调用订阅中心的函数即可。
/**
 * HunterUnion 负责任务函数的存储,实现形式为对象数组的入栈和遍历。
 * 内部数据结构为 :
 * topics: {
 *   'tiger1': [functionA(), functionB, function C],
 *   'tiger2': [functionA(), functionB, function C],
 * }
 */
let HunterUnion = {
  type: 'hunt',
  topics: Object.create(null),
  subscribe: function (topic, fn){
      if(!this.topics[topic]){
          this.topics[topic] = [];  
      }
      this.topics[topic].push(fn);
  },
  publish: function (topic, money){
      if(!this.topics[topic])
          return;
      for(let fn of this.topics[topic]){
        fn(money)
      }
  }
}

// Hunter只负责存储基本的订阅信息
function Hunter(name, level) {
  this.name = name;
  this.level = level;
}

Hunter.prototype.subscribe = function(topic, fn) {
  console.log(this.level + '猎人' + 
    this.name + '订阅了狩猎' + topic + '的任务');
  HunterUnion.subscribe(topic, fn);
}
Hunter.prototype.publish = function(topic, money) {
  console.log(this.level + '猎人' + 
    this.name + '发布了狩猎' + topic + '的任务');
    HunterUnion.publish(topic, money);
}

//猎人工会走来了几个猎人
let hunterMing = new Hunter('小明', '黄金')
let hunterJin = new Hunter('小金', '白银')
let hunterZhang = new Hunter('小张', '黄金')
let hunterPeter = new Hunter('Peter', '青铜')

hunterMing.subscribe('tiger', function(money){
  console.log('小明表示:' + (money > 200 ? '' : '不') + '接取任务')
})
hunterJin.subscribe('tiger', function(money){
  console.log('小金表示:接取任务')
})
hunterZhang.subscribe('tiger', function(money){
  console.log('小张表示:接取任务')
})
//Peter订阅了狩猎sheep的任务
hunterPeter.subscribe('sheep', function(money){
  console.log('Peter表示:接取任务')
})

//Peter发布了狩猎tiger的任务
hunterPeter.publish('tiger', 198)

3. 观察者模式是不是发布订阅模式

网上关于这个问题的回答,出现了两极分化,有认为发布订阅模式就是观察者模式的,也有认为观察者模式和发布订阅模式是真不一样的。

其实我不知道发布订阅模式是不是观察者模式,就像我不知道辨别模式的关键是设计意图还是设计结构(理念),虽然《JavaScript设计模式与开发实践》一书中说了分辨模式的关键是意图而不是结构。

如果以结构来分辨模式,发布订阅模式相比观察者模式多了一个中间件订阅器,所以发布订阅模式是不同于观察者模式的;如果以意图来分辨模式,他们都是实现了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新,那么他们就是同一种模式,发布订阅模式是在观察者模式的基础上做的优化升级。

不过,不管他们是不是同一个设计模式,他们的实现方式确实有差别,我们在使用的时候应该根据场景来判断选择哪个。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaScript设计模式:四、发布订阅模式 的相关文章

  • C++ : 力扣_Top(62-84)

    C 43 43 力扣 Top 62 84 文章目录 C 43 43 力扣 Top 62 84 62 不同路径 xff08 中等 xff09 66 加一 xff08 简单 xff09 69 x的平方根 xff08 中等 xff09 70 爬楼
  • PID参数整定具体方法-圆周倒立摆

    0 前言 关于PID参数的整定 xff0c 网上调节的口诀 原则 方法满天飞 xff0c 但是并没有具体的到步的教程 xff0c 作为初学者且非自动化相关专业学生有点看不懂 一脸懵逼 xff0c 走了不少弯路 xff0c 呕心沥血才调节好
  • 将字符串逐一入队,再出队列输出。

    C语言 创建一个简单链式队列代码 xff1a 将字符串逐一入队 xff0c 再出队列输出 队列是一种特殊的线性表 xff0c 特殊之处在于它只允许在表的前端 xff08 front xff09 进行删除操作 xff0c 而在表的后端 xff
  • cmake find_package找不到opencv

    当然找不到opencv可能是你安装的时候修改了安装位置 而按逻辑讲 xff0c 我们想让程序找到我的文件位置 xff0c 我们可以事先给程序位置信息 在CMakeLists txt写上我们地opencv的build的位置 set OpenC
  • 【精华】ROS学习(二):Realsense ROS驱动安装

    文章目录 Realsense ROS驱动安装1 系统环境及安装准备2 安装Realsense SDK3 安装Realsense ROS4 异常问题 1 异常问题1 2 异常问题2 Realsense ROS驱动安装 1 系统环境及安装准备
  • 20210202 电脑端开移动热点(无需任何软件,WIN10自带)

    卸载掉第三方软件 刚刚试了下 xff0c 如果连不上 xff0c 有可能是因为有梯子的原因 xff0c 关掉就能上网 或者先连上 xff0c 再开梯子
  • ROS Message 类型总结

    文章目录 ROS Message 类型总结内置类型 1 常见类型 2 自定义msg消息1 添加 msg 文件2 package xml3 CMakeLists txt ROS Message 类型总结 ROS使用简化的消息描述语言来描述RO
  • PHP的TZ环境变量是干什么的?底层原理是什么?

    PHP的TZ环境变量用于指定系统时区 底层原理是 xff0c PHP运行时可以读取环境变量 xff0c 以便确定系统时区并在日期和时间函数中使用 具体地说 xff0c 当PHP运行时 xff0c 它会检查系统的TZ环境变量 如果该环境变量存
  • HTTP响应是干什么的?为什么需要HTTP响应?底层原理是什么?

    HTTP响应是指服务器对客户端的HTTP请求所作出的回应 xff0c 它包含了HTTP协议规定的响应状态码 响应头部以及响应内容三个部分 HTTP响应的作用是将服务器端处理后的数据或结果返回给客户端 客户端发送HTTP请求后 xff0c 服
  • PHP对变量进行赋值的过程底层经历了什么?底层原理是什么?

    在PHP中 xff0c 对变量进行赋值的过程包括以下步骤 xff1a 解析器检查语法 xff1a PHP代码在执行之前 xff0c 首先需要进行语法解析 解析器会检查代码是否符合语法规范 xff0c 如果出现语法错误 xff0c 解析器会发
  • PHP为什么需要字符串处理函数?底层原理是什么?

    PHP作为一种脚本语言 xff0c 经常需要处理字符串数据 字符串处理函数是用于对字符串进行操作和处理的一组函数 xff0c 包括字符串的截取 查找 替换 转换等等操作 底层原理是PHP内核通过字符指针和字符数组来存储和处理字符串 xff0
  • PHP为什么需要抛出异常?底层原理是什么?

    在编程过程中 xff0c 可能会出现一些意外情况或者错误 xff0c 这些错误需要被捕获并处理 异常是一种错误处理机制 xff0c 它可以在程序出现异常情况时中断程序的正常执行流程 xff0c 跳转到异常处理代码块 xff0c 避免程序因错
  • PHP的代码注入是什么意思?底层原理是什么?

    PHP的代码注入 xff08 Code Injection xff09 指的是攻击者通过构造恶意的输入 xff0c 在应用程序中注入一些非法的代码 xff0c 从而在应用程序中执行攻击者的指令或代码 这种攻击方式通常会利用应用程序的漏洞 x
  • 信号量 Semaphore 用法及注意事项总结

    信号量 信号量在WIN32系统中是核心对象 xff0c 故其用法同其他同步机制类似 xff0c 但可应用于多个线程同步运行 xff0c 即同时有至多有限个线程同时工作 xff0c 而线程上线数量取决于初始化时指定的最大值 1 创建一个信号量
  • PHP的大数组是什么意思?有什么作用?底层原理是什么?

    在 PHP 中 xff0c 大数组指的是包含大量元素的数组 xff0c 其元素数量可以达到数百万或数千万甚至更多 这种数组在处理大规模数据时非常有用 xff0c 例如在数据分析 机器学习和科学计算等领域中 PHP 的大数组的实现方式可以采用
  • PHP的全局变量是是干什么的?有什么作用?底层原理是什么?

    PHP的全局变量是指在整个PHP脚本中都可以被访问到的变量 这些变量存储在PHP进程的内存中 xff0c 并在整个脚本执行期间保持不变 全局变量的作用是在不同的函数和代码块中共享数据 xff0c 从而使代码更加简洁和易于维护 全局变量的底层
  • PHP的日志是干什么的?有什么用?底层原理是什么?

    在软件开发中 xff0c 日志是记录系统活动的重要方式之一 xff0c 也是排查问题和故障排除的主要工具之一 PHP提供了多种日志记录方式 xff0c 如文件日志 数据库日志和Syslog等 它们的共同目的是在代码执行时收集和记录信息 xf
  • PHP的开发环境和部署环境是什么意思?底层原理是什么?

    PHP的开发环境和部署环境是指在开发和部署PHP应用程序时所使用的不同环境 开发环境通常是指程序员在本地开发PHP应用程序的环境 xff0c 其目的是为了让程序员能够快速开发和测试应用程序 xff0c 同时方便调试和排除问题 在开发环境中
  • PHP为什么需要错误报告级别?底层原理是什么?

    PHP提供了多种错误报告级别 xff0c 包括错误信息 警告信息 提示信息和严格模式等 xff0c 用于在开发过程中捕获和处理错误 底层原理是通过PHP的内部错误处理机制来实现的 当PHP执行脚本时 xff0c 如果出现了错误 xff0c
  • PHP的代码调试技巧是什么意思?底层原理是什么?

    PHP的代码调试技巧是指在开发过程中 xff0c 通过调试技术来解决代码中的问题 xff0c 提高代码的可靠性和稳定性 这些技巧可以帮助开发人员快速定位代码中的错误 xff0c 提高代码的质量和效率 PHP提供了多种调试技术 xff0c 包

随机推荐

  • PHP的mysqli扩展和mysql扩展的区别是什么?底层原理是什么?

    mysqli和mysql扩展都是PHP提供的操作MySQL数据库的扩展 它们的区别在于mysqli扩展是MySQL Improved Extension的简写 xff0c 是mysql扩展的改进版 xff0c 提供了更好的性能和更多的功能
  • PHP的依赖关系是什么意思?底层原理是什么?

    PHP的依赖关系指的是PHP应用程序或库与其他软件包或库之间的关系 这些软件包或库可能包括操作系统提供的库 xff0c 例如文件I O和网络功能 xff0c 也可能包括第三方库 xff0c 例如数据库客户端库和图像处理库 底层原理是 xff
  • 什么是Composer?底层原理是什么?

    Composer是PHP的一个依赖管理工具 xff0c 它可以帮助开发者在项目中自动管理依赖关系 xff0c 例如第三方库 框架 组件等 通过Composer xff0c 可以在项目中添加 更新 卸载依赖项 xff0c 并自动解析它们的依赖
  • 为什么composer可以自动管理依赖关系?底层原理是什么?

    Composer能够自动管理依赖关系的原理是基于包管理和自动加载的机制 首先 xff0c Composer通过一个名为Packagist的在线包存储库来管理各种PHP包 xff0c 这个仓库中包含了大量的PHP库和框架 xff0c 开发者可
  • windows线程同步-事件Event用法总结

    事件对象 Win32 中最具弹性的同步机制就属 events 对象了 Event 对象是一种核 心对象 xff0c 它的唯一目的就是成为激发状态或未激发状态 这两种状态全由程序 来控制 xff0c 不会成为 Wait 函数的副作用 Even
  • composer.lock是干什么的?底层原理是什么?

    composer lock文件是Composer工具在安装依赖包时生成的一个锁文件 它记录了当前应用程序所依赖的所有PHP库及其版本号 xff0c 以及所有依赖库所依赖的其他库及其版本号等信息 在运行composer install命令时
  • PHP的Zend引擎是干什么的?底层原理是什么?

    PHP的Zend引擎是PHP解释器的核心组件 xff0c 负责将PHP代码转换为可执行的指令集 xff0c 并执行这些指令 Zend引擎是PHP的默认执行引擎 xff0c 被广泛使用 Zend引擎的底层原理可以分为以下几个关键步骤 xff1
  • PHP解释器是干什么的?底层原理是什么?

    PHP解释器是用于解释执行PHP代码的软件程序 它负责将编写的PHP代码转换为可执行的机器指令 xff0c 并执行这些指令以实现代码的功能 PHP解释器的底层原理可以分为以下几个步骤 xff1a 词法分析 xff08 Lexical Ana
  • PHP代码的底层是什么?底层原理是什么?

    PHP代码的底层是由计算机可执行的机器码 xff08 二进制指令 xff09 组成 底层原理是将PHP代码经过编译和解释执行的过程转化为机器码 底层原理可以分为以下几个步骤 xff1a 词法分析 xff08 Lexical Analysis
  • Jetson Xavier NX 的SD卡系统镜像制作

    Jetson Xavier NX 的SD卡系统镜像制作 一 SD卡系统查看二 系统镜像制作三 系统镜像烧录 一 SD卡系统查看 现有的SD卡的内存为128G xff0c 其中64G内存并未分配 span class token commen
  • 嵌入式Linux下使用crond服务

    参考 xff1a https www linuxidc com Linux 2014 02 97369 htm http www linuxidc com Linux 2014 02 97360 htm https blog csdn ne
  • 关于Flexsns Sky 卡80%,以及乱码的解决问题

    一直被 flexsns sky 这个应用折磨好久了 xff0c 刚开始的时候安装成功 但是打开界面一直卡在80 那里 xff0c ucenter 里面的设置也是对的 官网也是挂的 xff01 于是百思不得解 接下来 我来说说我的解决办法把
  • Ubuntu18.04运行ORB-SLAM3(Demo+本地Realsense D415运行)

    ORB SLAM3论文地址 xff1a https arxiv org abs 2007 11898 代码地址 xff1a https github com UZ SLAMLab ORB SLAM3 一 安装库 根据ORB SLAM3源代码
  • ROS中的坐标与坐标系转换

    ROS中的TF 官网建议新工作直接使用tf2 xff0c 因为它有一个更清洁的界面 xff0c 和更好的使用体验 xff08 自ROS Hydro以来 xff0c tf第一代已被 弃用 xff0c 转而支持tf2 xff09 TF介绍 TF
  • 激光雷达与相机融合(二)-----基于openCV的YOLO目标检测

    代码解析 1 加载模型 span class token comment load image from file span cv span class token operator span Mat img span class toke
  • 线程优先权Thread Priority概念总结

    全文参考 WIN32多线程设计 一书 为什么会有线程优先权 xff1a 为什么CPU处理线程时会按优先级执行 xff1f 想象在忙碌的一天中 xff0c 有很多事情待做但时间又不够 xff0c 其中有很多紧急的事情 比如当晚的英语在线测试
  • 将ros cv_bridge关联到自己安装的Opencv版本

    有时候需要同时使用较高版本的openCV 但一般默认安装的ros系统的cv bridge包关联的Opencv版本都较低 xff0c 这时候就需要将cv bridge关联到自己安装的高版本OpenCV 成功方法为第三条 xff0c 前两条为遇
  • chmod +x 与chmod 777的区别

    chmod 43 x 是将文件状态改为可执行 xff0c 而chmod 777 是改变文件读写权限 在linux中使用man命令查看chmod的大纲我们可以得出以下有用的信息 xff1a chmod OPTION MODE MODE FIL
  • WIndowsServer2012 DHCP服务器配置

    DHCP服务器配置 WIndowsServer2012 DHCP服务器配置服务器配置保留IP设置作用域选项 客户机设置 WIndowsServer2012 DHCP服务器配置 服务器配置 1 首先打开服务器管理器 xff0c 点击工具 xf
  • JavaScript设计模式:四、发布订阅模式

    JavaScript设计模式 xff1a 四 发布订阅模式 文章目录 JavaScript设计模式 xff1a 四 发布订阅模式一 概述1 观察者模式2 发布订阅模式3 观察者模式是不是发布订阅模式 一 概述 观察者模式 xff1a 观察者