观察者模式和发布订阅模式的区别

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

二 概念上的区别

1.观察者模式,目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口。具体观察者和具体目标继承各自的基类,然后具体观察者把自己注册到具体目标里,在具体目标发生变化时候,调度观察者的更新方法。

比如有个“天气中心”的具体目标A,专门监听天气变化,而有个显示天气的界面的观察者B,B就把自己注册到A里,当A触发天气变化,就调度B的更新方法,并带上自己的上下文。

2.发布订阅,订阅者把自己想订阅的事件注册到调度中心,当该事件触发时候,发布者发布该事件到调度中心(顺带上下文),由调度中心统一调度订阅者注册到调度中心的处理代码。

比如有个界面是实时显示天气,它就订阅天气事件(注册到调度中心,包括处理程序),当天气变化时(定时获取数据),就作为发布者发布天气信息到调度中心,调度中心就调度订阅者的天气处理程序。

三、发布订阅模式简介

1)定义和原理
发布订阅模式是一种消息传递模式,其中发布者发布消息,而订阅者接收和处理这些消息。它是一种松耦合的通信方式,允许发布者和订阅者在不知道彼此存在的情况下进行通信。

发布订阅模式的原理基于消息队列或主题,发布者将消息发布到特定的消息队列或主题中,而订阅者可以订阅这些消息队列或主题以接收和处理消息。发布者和订阅者之间的通信是异步的,这意味着发布者发布消息后,订阅者可以在任何时候接收和处理消息。

发布订阅模式的核心思想是将发布者和订阅者解耦,使得它们可以独立地运行和扩展。这种解耦有助于提高系统的灵活性和可伸缩性,因为发布者和订阅者可以根据需要进行扩展和修改,而不会影响彼此的操作。

发布订阅模式在许多领域都有应用,如

  • 消息队列
  • 事件驱动架构
  • 实时数据更新
  • 消息推送

它是一种非常有用的通信模式,可以帮助开发人员构建高效、可靠和可扩展的系统。

2) 发布订阅模式的优势
发布订阅模式具有以下优势:
  1. 解耦:发布者和订阅者是松耦合的,它们可以独立地运行和扩展,而不会相互影响。
  2. 灵活性:发布者可以随时发布消息,而订阅者可以随时订阅和取消订阅消息,这使得系统更加灵活。
  3. 可伸缩性:发布者和订阅者可以根据需要进行扩展和修改,而不会影响彼此的操作。
  4. 异步通信:发布者和订阅者之间的通信是异步的,这意味着发布者发布消息后,订阅者可以在任何时候接收和处理消息。
  5. 消息过滤:订阅者可以根据自己的需求订阅特定的消息,从而实现消息过滤。
  6. 可靠性:发布订阅模式通常使用消息队列或主题来存储消息,这可以确保消息不会丢失,并且可以在订阅者不可用时进行存储。
  7. 分布式系统:发布订阅模式可以在分布式系统中使用,从而实现跨节点的通信。

 

四、发布订阅模式的实现

1)消息队列
发布订阅模式可以使用消息队列来实现。消息队列是一种存储和转发消息的技术,它可以在发布者和订阅者之间提供异步通信。

在发布订阅模式中,发布者将消息发布到消息队列中,而订阅者可以从消息队列中接收和处理消息。消息队列可以作为发布者和订阅者之间的中间件,它可以确保消息的可靠性和有序性。

使用消息队列实现发布订阅模式的步骤如下:

  1. 创建消息队列:创建一个消息队列来存储和转发消息。
  2. 发布消息:发布者将消息发布到消息队列中。
  3. 订阅消息:订阅者订阅消息队列以接收和处理消息。
  4. 处理消息:订阅者从消息队列中接收消息并进行处理。

在实现发布订阅模式时,需要考虑以下几个方面:

  1. 消息队列的选择:根据需求选择合适的消息队列,如 RabbitMQ、Kafka 等。
  2. 消息的格式:定义消息的格式,以便发布者和订阅者能够理解和处理消息。
  3. 消息的发布和订阅:确定发布者和订阅者如何发布和订阅消息。
  4. 消息的处理:订阅者需要根据自己的需求处理消息,如数据处理、日志记录等。
  5. 消息的可靠性:考虑如何确保消息的可靠性,如消息确认、消息重试等。
  6. 消息的有序性:考虑如何确保消息的有序性,如消息排序、消息分组等。

总之,使用消息队列实现发布订阅模式可以提供高效、可靠和可扩展的通信方式。在实现时,需要根据具体需求进行选择和配置。

2)发布订阅者
在发布订阅模式中,发布者和订阅者是两个独立的实体,它们通过某种通信渠道(如消息队列)进行交互。

发布者负责将消息发布到通信渠道中,而订阅者则负责从通信渠道中接收和处理消息。发布者和订阅者之间的通信是异步的,这意味着发布者发布消息后,订阅者可以在任何时候接收和处理消息。

以下是使用发布订阅模式实现发布者和订阅者的基本步骤:

  1. 创建通信渠道:创建一个消息队列或主题来存储和转发消息。
  2. 发布消息:发布者将消息发布到通信渠道中。
  3. 订阅消息:订阅者订阅通信渠道以接收和处理消息。
  4. 处理消息:订阅者从通信渠道中接收消息并进行处理。

在实现发布订阅模式时,需要考虑以下几个方面:

  1. 通信渠道的选择:根据需求选择合适的通信渠道,如消息队列、主题等。
  2. 消息的格式:定义消息的格式,以便发布者和订阅者能够理解和处理消息。
  3. 消息的发布和订阅:确定发布者和订阅者如何发布和订阅消息。
  4. 消息的处理:订阅者需要根据自己的需求处理消息,如数据处理、日志记录等。
  5. 消息的可靠性:考虑如何确保消息的可靠性,如消息确认、消息重试等。
  6. 消息的有序性:考虑如何确保消息的有序性,如消息排序、消息分组等。
  7. 总之,发布订阅模式实现发布者和订阅者之间的通信,提供了一种高效、可靠和可扩展的通信方式。在实现时,需要根据具体需求进行选择和配置。
3)消息主题
在发布订阅模式中,消息主题是用于发布和订阅消息的标识符。它是发布者和订阅者之间的桥梁,用于定义订阅者感兴趣的消息类型。

以下是使用消息主题实现发布订阅模式的基本步骤:

  1. 创建消息主题:创建一个唯一的消息主题来标识要发布的消息类型。
  2. 发布消息:发布者将消息发布到特定的消息主题中。
  3. 订阅消息:订阅者订阅特定的消息主题以接收和处理消息。
  4. 处理消息:订阅者从订阅的消息主题中接收消息并进行处理。

在实现发布订阅模式时,需要考虑以下几个方面:

  1. 消息主题的设计:设计合适的消息主题,以便发布者和订阅者能够理解和处理消息。
  2. 消息的发布和订阅:确定发布者和订阅者如何发布和订阅消息主题。
  3. 消息的处理:订阅者需要根据自己的需求处理消息,如数据处理、日志记录等。
  4. 消息的可靠性:考虑如何确保消息的可靠性,如消息确认、消息重试等。
  5. 消息的有序性:考虑如何确保消息的有序性,如消息排序、消息分组等。

总之,消息主题是发布订阅模式中的重要概念,用于定义发布者和订阅者之间的通信。在实现时,需要根据具体需求进行选择和配置。

五、发布订阅模式的

  1. 应用场景
  2. 实时数据更新
  3. 消息推送
  4. 事件驱动架构
  5. 注意事项
  6. 消息丢失和重复
  7. 消息顺序问题
  8. 消息过期问题

六 总结

1. 最大的区别是调度的地方。

虽然两种模式都存在订阅者和发布者(具体观察者可认为是订阅者、具体目标可认为是发布者),但是观察者模式是由具体目标调度的,而发布/订阅模式是统一由调度中心调的,所以观察者模式的订阅者与发布者之间是存在依赖的,而发布/订阅模式则不会。2. 两种模式都可以用于松散耦合,改进代码管理和潜在的复用。

七, 代码如下

观察者模式

// 观察者
class Observer {
    constructor() {
 
    }
    update(val) {
 
    }
}
// 观察者列表
class ObserverList {
    constructor() {
        this.observerList = []
    }
    add(observer) {
        return this.observerList.push(observer);
    }
    remove(observer) {
        this.observerList = this.observerList.filter(ob => ob !== observer);
    }
    count() {
        return this.observerList.length;
    }
    get(index) {
        return this.observerList(index);
    }
}
// 目标
class Subject {
    constructor() {
        this.observers = new ObserverList();
    }
    addObserver(observer) {
        this.observers.add(observer);
    }
    removeObserver(observer) {
        this.observers.remove(observer);
    }
    notify(...args) {
        let obCount = this.observers.count();
        for (let index = 0; index < obCount; index++) {
            this.observers.get(i).update(...args);
        }
    }
}

 发布/订阅模式

class PubSub {
    constructor() {
        this.subscribers = {}
    }
    subscribe(type, fn) {
        if (!Object.prototype.hasOwnProperty.call(this.subscribers, type)) {
          this.subscribers[type] = [];
        }
        
        this.subscribers[type].push(fn);
    }
    unsubscribe(type, fn) {
        let listeners = this.subscribers[type];
        if (!listeners || !listeners.length) return;
        this.subscribers[type] = listeners.filter(v => v !== fn);
    }
    publish(type, ...args) {
        let listeners = this.subscribers[type];
        if (!listeners || !listeners.length) return;
        listeners.forEach(fn => fn(...args));        
    }
}
 
let ob = new PubSub();
ob.subscribe('add', (val) => console.log(val));
ob.publish('add', 1);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/398959.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【探究大语言模型中G、P、T各自的作用】

文章目录 前言一、GPT全称二、Generative&#xff1a;生成式三、Pre-trained&#xff1a;预训练四、Transformer&#xff1a;变换模型 前言 偷偷告诉你们&#xff0c;在写这篇文章时&#xff0c;标题就是用chatGPT生成的 一、GPT全称 大语言模型的全称是Generative Pre-train…

[嵌入式AI从0开始到入土]15_orangepi_aipro欢迎界面、ATC bug修复、镜像导出备份

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注&#xff1a;等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间&#xff0c;后期会考虑出视频教程&#xff0c;务必催更&#xff0c;以防我变身鸽王。 第1期 昇腾Altas 200 DK上手 第2期 下载昇腾案例并运行 第3期 官…

同城系统源码_城市o2o系统源码OctShop

同城系统源码O2O的模式就是一种将线下商品或服务与线上互联网相结合&#xff0c;让互联网成为线下交易的前台。比如&#xff1a;商家企业可以通过线上的方式展示自己商品或服务的详细信息&#xff0c;以及各种营销活动的宣传&#xff0c;引导买家消费者下单&#xff0c;通过线上…

Java的String类

目录 String类的常用方法 1.1 字符串构造 1.2 String对象的比较 1.3 字符串查找 1.4 转换 1.5 字符串替换 1.6字符串拆分 1.7 字符串截取 1.8 其他操作方法 1.9 字符串的不可变性 1.10 字符串修改 String类的常用方法 1.1 字符串构造 String类常用的构造方法有很多…

优化|非强凸问题的一阶算法线性收敛条件(一)

原文信息&#xff08;包括题目、发表期刊、原文链接等&#xff09;&#xff1a;Linear convergence of first order methods for non-strongly convex optimization 原文作者&#xff1a;I. Necoara, Yu. Nesterov, F. Glineur 论文解读者&#xff1a;陈宇文 编者按&#xf…

LabVIEW压电驱动迟滞补偿控制

LabVIEW压电驱动迟滞补偿控制 随着精密控制技术的迅速发展&#xff0c;压电陶瓷驱动器因其高精度和快速响应特性&#xff0c;在微纳精密定位系统中得到了广泛应用。然而&#xff0c;压电材料固有的迟滞非线性特性严重影响了其定位精度和重复性。开发了一种基于LabVIEWFPGA的压…

WSL里的Ubuntu 登录密码忘了怎么更改

环境&#xff1a; Win10 专业版 WSL2 如何 Ubuntu22.04 问题描述&#xff1a; WSL里的Ubuntu 登录密码忘了怎么更改 解决方案&#xff1a; 在WSL中的Ubuntu系统中&#xff0c;忘记了密码&#xff0c;可以通过以下步骤重置密码&#xff1a; 1.打开命令提示符或PowerShel…

HTTP的详细介绍

目录 一、HTTP 相关概念 二、HTTP请求访问的完整过程 1、 建立连接 2、 接收请求 3、 处理请求 3.1 常见的HTTP方法 3.2 GET和POST比较 4、访问资源 5、构建响应报文 6、发送响应报文 7、记录日志 三、HTTP安装组成 1、常见http 服务器程序 2、apache介绍和特点 …

Idea中使用git将多次提交记录合并成一次提交记录

一、查看Idea中的提交记录 查看Idea中的提交记录&#xff0c;我们希望将新增了bbb.txt、新增了ccc.txt、新增了ddd.txt,这三次提交记录合并成一次提交记录。 二、使用Interactively Rebase from Here进行合并 2.1、把鼠标放在新增了bbb.txt这次提交记录上并右键单击 把鼠标放…

文件上传漏洞--Upload-labs--Pass17--条件竞争

一、条件竞争原理&#xff08;结合代码审计&#xff09; 1、首先进行代码审计&#xff0c;查看源代码。 我们可知&#xff0c;将文件上传至服务器后&#xff0c;不会被立即删除&#xff0c;而是做短暂的停留&#xff0c;中间会有一小部分时间差&#xff0c;这部分时间差是代码…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月21日,星期三

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月21日 星期三 农历正月十二 1、 央行&#xff1a;5年期LPR下调25个基点至3.95%。100万元房贷30年少还5.2万元。 2、 民航局等四部门明确&#xff1a;到2025年&#xff0c;机场噪声污染防控标准体系基本建成。 3、 应急…

云数据库 Redis 性能深度评测(阿里云、华为云、腾讯云、百度智能云)

在当今的云服务市场中&#xff0c;阿里云、腾讯云、华为云和百度智能云都是领先的云服务提供商&#xff0c;他们都提供了全套的云数据库服务&#xff0c;其中 Redis属于RDS 之后第二被广泛应用的服务&#xff0c;本次测试旨在深入比较这四家云服务巨头在Redis云数据库性能方面的…

相机图像质量研究(25)常见问题总结:CMOS期间对成像的影响--过曝、欠曝

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

欲速则不达,慢就是快!

引言 随着生活水平的提高&#xff0c;不少人的目标从原先的解决温饱转变为追求内心充实&#xff0c;但由于现在的时间过得越来越快以及其他外部因素&#xff0c;我们对很多东西的获取越来越没耐心&#xff0c;例如书店经常会看到《7天精通Java》、《3天掌握XXX》等等之类的书籍…

《最新出炉》系列初窥篇-Python+Playwright自动化测试-23-处理select下拉框-下篇

1.简介 上一篇中宏哥主要讲解和分享了一下&#xff0c;我们常见或者传统的select下拉框的操作&#xff0c;但是近几年又出现了了一种新的select下拉框&#xff0c;其和我们传统的select下拉框完全不一样&#xff0c;那么我们如何使用playwright对其进行定位操作了。宏哥今天就…

[word] 如何将word文本转换成表格? #知识分享#学习方法#媒体

如何将word文本转换成表格&#xff1f; 如何将word文本转换成表格&#xff1f;不管是Word入门新手还是老手&#xff0c;相信这个技巧会让你更加熟练Word&#xff0c;操作起来得心应手&#xff01; 1.文本转换成表格 同样的要怎么把一堆凌乱的数据转换成表格呢&#xff1f;这里…

Java基础常用API(1)

文章目录 1&#xff1a;API 概述1.1 API概述和课程安排1.2 包和导包 2&#xff1a;Scanner2.1 Scanner基本使用2.2 练习(数据求和) 3&#xff1a;Random3.1 Random基本使用3.2 练习(猜数字游戏) 1&#xff1a;API 概述 1.1 API概述和课程安排 我们在讲解面向对象的时候&#…

NestJS入门6:日志中间件

前文参考&#xff1a; NestJS入门1 NestJS入门2&#xff1a;创建模块 NestJS入门3&#xff1a;不同请求方式前后端写法 NestJS入门4&#xff1a;MySQL typeorm 增删改查 NestJS入门5&#xff1a;加入Swagger 1. 安装 nest g middleware logger middleware​ ​ ​ 2. lo…

嵌入式linux开发之LAN8720A网络驱动

网络硬件组成 OSI模型和TCP/IP模型的对比 嵌入式网络硬件分为两部分&#xff1a;MAC 和 PHY。 MAC&#xff08;Medium Access Control&#xff09;和PHY&#xff08;Physical Layer&#xff09;是计算机网络领域中常见的术语&#xff0c;通常用于描述数据链路层&#xff08;…

java数据结构与算法刷题-----LeetCode503. 下一个更大元素 II

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 解题思路&#xff1a;时间复杂度和空间复杂度都是O(n) 此题是739题的衍生题…