你对 观察者模式(Observer Pattern)和 发布-订阅模式(Publisher-Subscriber Pattern)的描述是非常准确的,并且阐明了它们的核心区别。为了帮助你更好地理解这两者的细微差异,下面是一个更详细的对比分析:

1. 观察者模式(Observer Pattern)

概念:

  • 观察者模式是一种 行为型设计模式,用于定义对象之间一对多的依赖关系。当一个对象的状态发生变化时,所有依赖于它的对象都会自动更新。通常,这些依赖对象被称为“观察者”。

工作流程:

  1. 主题(Subject):发布事件的对象。当主题的状态发生变化时,它会通知所有已注册的观察者。
  2. 观察者(Observer):订阅主题的对象。当主题状态变化时,观察者会收到通知并执行相关的操作。

实现方式:

  • 观察者模式通常没有中介,观察者直接订阅主题(即,主题直接管理观察者)。当主题的状态发生变化时,主题会直接通知所有已注册的观察者。

应用场景:

  • UI 更新:在前端开发中,通常有多个视图组件需要更新。例如,React 和 Vue 中的响应式数据绑定就是基于观察者模式来实现的。
  • 事件处理:浏览器中的 DOM 事件模型(如 click, hover 等)也采用了观察者模式。

代码示例(JavaScript)

// 主题
class Subject {constructor() {this.observers = [];}// 注册观察者subscribe(observer) {this.observers.push(observer);}// 通知观察者notify() {this.observers.forEach(observer => observer.update());}
}// 观察者
class Observer {update() {console.log('State has been updated');}
}const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();subject.subscribe(observer1);
subject.subscribe(observer2);subject.notify();  // 输出 "State has been updated" 两次

特点:

  • 紧密耦合:观察者直接与主题连接,主题必须管理所有观察者的订阅和通知。
  • 同步通知:当主题状态变化时,所有观察者都会同步地被通知。

2. 发布-订阅模式(Publisher-Subscriber Pattern)

概念:

  • 发布-订阅模式也是一种 行为型设计模式,它允许发布者和订阅者之间解耦。发布者发布消息,订阅者订阅感兴趣的消息。在该模式下,发布者和订阅者没有直接的依赖关系,它们通过 中介(事件总线、消息调度中心) 进行通信。

工作流程:

  1. 发布者(Publisher):发布消息的对象。它发布某种类型的事件或消息,但不需要知道谁会接收这些消息。
  2. 订阅者(Subscriber):订阅消息的对象。它将自己感兴趣的事件注册到调度中心(事件总线),并在事件发布时接收通知。
  3. 调度中心(Event Channel / Event Bus):事件的中介,负责接收消息并将它们分发到所有订阅了该消息的订阅者。

实现方式:

  • 发布-订阅模式通过中介来解耦发布者和订阅者,通常采用 事件总线消息队列 来处理事件的注册和分发。当某个事件发生时,调度中心会通知所有相关的订阅者。

应用场景:

  • 前端框架的事件系统:如 Vue.js 的事件系统和 React 中的状态管理。
  • 微服务架构:多个服务之间的消息通信通常采用发布-订阅模式,确保服务之间松耦合。

代码示例(JavaScript)

class EventBus {constructor() {this.events = {};}// 订阅事件subscribe(event, callback) {if (!this.events[event]) {this.events[event] = [];}this.events[event].push(callback);}// 发布事件publish(event, data) {if (this.events[event]) {this.events[event].forEach(callback => callback(data));}}// 注销订阅unsubscribe(event, callback) {if (this.events[event]) {this.events[event] = this.events[event].filter(cb => cb !== callback);}}
}const eventBus = new EventBus();// 订阅事件
eventBus.subscribe('dataReceived', (data) => {console.log('Received data:', data);
});// 发布事件
eventBus.publish('dataReceived', { message: 'Hello World' });// 注销订阅
eventBus.unsubscribe('dataReceived', (data) => {console.log('Received data:', data);
});

特点:

  • 松散耦合:发布者和订阅者之间没有直接依赖关系,所有的交互通过事件总线进行。
  • 异步通知:订阅者接收到消息的方式通常是异步的。

关键区别:

特性观察者模式发布-订阅模式
依赖关系观察者直接订阅主题。主题管理观察者。发布者和订阅者通过中介(事件总线)进行通信,发布者和订阅者互不直接依赖。
解耦程度观察者和主题之间的耦合较高,主题负责管理所有观察者。高度解耦,订阅者与发布者通过事件总线等中介通信。
通知方式通常是同步通知。通常是异步通知。
使用场景适用于需要状态通知、更新界面的场景,如 UI 更新。适用于事件驱动的系统,尤其是在微服务或消息队列中常见。
复杂度简单,通常由一个主题直接管理观察者。需要一个中介(事件总线),更适用于较为复杂的系统。
事件的处理方式观察者直接与主题互动。订阅者通过中介接收和处理消息。

总结

  • 观察者模式 强调的是一对多的直接依赖关系,主要用于更新界面或执行某些操作。
  • 发布-订阅模式 提供了更高的灵活性和解耦,适用于更复杂的系统,其中发布者和订阅者不直接依赖,而是通过中介进行事件的传递。

根据应用的复杂度和系统的需求,选择合适的模式可以有效提高系统的灵活性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/90892.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/90892.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/90892.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年接口技术的十字路口:当MCP遇见REST、GraphQL与gRPC

在当今这个由数据驱动、万物互联的时代,应用程序接口(API)已成为现代软件架构的基石。它们是不同服务之间沟通的桥梁,支撑着从网页应用到复杂的微服务生态系统的一切。长久以来,开发者们在REST、GraphQL和gRPC这几种主…

【CTF-WEB-反序列化】利用__toString魔术方法读取flag.php

题目 页面提示输入?code,那我们在网址里get一下出现了新页面的提示,进入看看下面有个help.php页面的提示,进入看看有一段php代码,仔细分析,应该是要用反序列法代码如下 class FileClass{ public $filename error.log…

在 github.com 与 sourceforge.net 上创建免费个人静态网站、博客的区别

github.com github 属于 git 版本管理专业网站,有免费和收费两种套餐。git 的数据是存放在数据库中的,要将数据库中的数据显示为网站的网页,这需要服务器端提供专门的中间件支持才能实现。 特点: 官方支持:提供长期…

jenkins 入门指南:从安装到启动的完整教程

jenkins 入门指南:从安装到启动的完整教程 持续集成(CI)是现代开发流程中的核心环节,而 Jenkins 作为一款开源的 CI 工具,凭借简单安装、开箱即用、插件丰富、易于扩展等优势,成为开发者的首选工具。它能自…

机器学习(重学版)基础篇(概念与评估)

本篇参考周志华老师的西瓜书,但是本人学识有限仅能理解皮毛,如有错误诚请读友评论区指正,万分感谢。一、基础概念与评估方法本节目标:建立理论基础框架​1、机器学习定义机器学习是一门通过计算手段利用经验(以数据形式…

spring/springboot SPI(二)配合使用的接口

spring.factories 里,Spring 会根据接口来加载实现类,常见的几个接口包括:一、org.springframework.context.ApplicationListener1、作用监听 Spring 容器事件,如 ApplicationReadyEvent。2、使用方法项目结构Spring Boot 2.xSpri…

基于Zig语言,opencv相关的c++程序静态交叉编译

一、写在前面 1.什么是zig? Zig 是一种通用编程语言; Zig 最初的定位就是代替C语言的系统级语言,它提供了与 C 语言几乎 100% 兼容(可直接调用 C 头文件、链接 C 库),同时不需要任何依赖构建系统。 Zig 同时附带一…

基于 LSTM 与 SVM 融合的时间序列预测模型:理论框架与协同机制—实践算法(1)

目录 1、单一模型的局限性:混合架构的设计动机 2、LSTM 的时序特征提取:从原始序列到高阶表征 2.1、门控机制的时序过滤能力 2.2、隐藏状态的特征压缩作用 2.3、预训练的特征优化逻辑 3、SVM 的非线性映射:从高阶特征到预测输出 3.1、…

如何查看docker实例是否挂载目录,以及挂载了哪些目录

一条命令即可一次性列出当前容器里所有挂载点&#xff1a; docker inspect <容器ID或名称> --format{{range .Mounts}}{{printf "%-8s %-35s -> %s\n" .Type .Source .Destination}}{{end}}示例输出&#xff1a; bind /host/owrt/src …

Opentrons 模块化平台与AI技术助力智能移液创新,赋能AAW™自动化工作站

在生命科学领域加速拥抱自动化的关键节点&#xff0c;全球开源实验室自动化领导者 Opentrons 携手全球领先生命科学公司默克生命科学&#xff0c;重磅推出 AAW™智能自动化液体处理平台。这一战略合作的核心技术引擎 ——Opentrons Flex 第三代全自动移液工作站&#xff0c;正以…

C++学习笔记(八:函数与变量)

往篇内容&#xff1a; C学习笔记&#xff08;一&#xff09; 一、C编译阶段※ 二、入门案例解析 三、命名空间详解 四、C程序结构 C学习笔记&#xff08;二&#xff09; 五、函数基础 六、标识符 七、数据类型 补充&#xff1a;二进制相关的概念 sizeof 运算符简介 补…

智慧施工:施工流程可视化管理系统

图扑智慧施工全流程可视化管理系统&#xff0c;通过可视化界面&#xff0c;可直观掌握各工序衔接进度、资源调配情况&#xff0c;快速识别违规作业、设备故障等风险点 —— 如塔吊运行半径重叠、深基坑支护位移预警等。同时&#xff0c;系统支持施工方案模拟推演&#xff0c;对…

单链表的冒泡排序实现:从原理到代码详解

单链表的冒泡排序实现&#xff1a;从原理到代码详解 引言 单链表作为一种常见的数据结构&#xff0c;其排序操作因节点无法随机访问&#xff08;需通过指针遍历&#xff09;而与数组排序存在差异。冒泡排序因其实现简单、无需额外空间&#xff08;仅需指针操作&#xff09;&…

如何在 Ubuntu 24.04 或 22.04 上安装和使用 GDebi

APT 是 Ubuntu 上安装需要外部依赖项的 Debian 包的一种方式,但还有另一种选择,即 GDebi。本文将介绍如何在 Ubuntu 24.04 上安装 GDebi,以及如何使用它来安装 .deb 包所需的依赖项。 什么是 GDebi? GDebi 是默认的 .deb 包安装器 DPKG 的轻量级替代品。与 DPKG 不同,GD…

俄罗斯方块游戏开发(面向对象编程)

摘要本设计基于MATLAB面向对象编程技术&#xff0c;开发了一款具备完整游戏逻辑的俄罗斯方块游戏。通过类封装实现游戏核心模块&#xff08;方块管理、游戏板状态、碰撞检测等&#xff09;&#xff0c;采用旋转矩阵实现方块变形&#xff0c;结合MATLAB图形用户界面&#xff08;…

背包DP之多重背包

背包DP之多重背包一、多重背包基础认知1.1 问题定义1.2 核心特征二、基础解法&#xff1a;暴力拆分2.1 核心思路2.2 代码实现2.3 局限性分析三、优化解法&#xff1a;二进制拆分3.1 优化原理3.2 拆分步骤3.3 代码实现3.4 复杂度分析四、二进制拆分过程五、多重背包的变种与应用…

Ansible 变量指南:声明、优先级、作用域与最佳实践(一)

Ansible 变量的声明 前言 全面理解 Ansible 变量是编写高效、可维护 Playbook 的关键。由于最近使用 Ansible 比较多&#xff0c;在变量问题上踩了不少坑&#xff0c;也因此对变量的声明&#xff0c;优先级和作用域有了更深的理解。姑且总结一下&#xff0c;分享给大家&#…

[极客大挑战 2019]FinalSQL--布尔盲注

直接看题可以看到题目给了提示盲注&#xff01;那么接下来就是寻找注入点了&#xff01;那么不能发现注入点就是id了&#xff01;注入类型为数值型注入&#xff01;这里直接尝试盲注。但是这里and被过滤了&&也不行。问了几个师傅说用or&#xff0c;但是空格被过滤了&am…

再谈fpga开发(状态机的应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】前面说过&#xff0c;fpga上面最基础的部分是寄存器&#xff0c;而所有寄存器存在每一个clock下&#xff0c;都有被翻转的可能性。至于这些寄存器是…

TCP如何解决网络切换问题

一、传统TCP的网络切换问题核心问题&#xff1a;TCP 连接基于四元组&#xff08;源IP、源端口、目的IP、目的端口&#xff09;&#xff0c;IP 变化导致连接失效二、改进方案与技术演进1. MPTCP&#xff08;多路径TCP&#xff09; - 主流解决方案核心机制&#xff1a;单连接多路…