当前位置: 首页 > news >正文

从Vue层面 - 解析发布订阅模式和观察者模式区别

目录

  • 前言
  • 一、发布订阅模式
    • 什么是发布订阅模式?
    • 应用场景
  • 二、观察者模式
    • 1)什么是观察者模式?
    • 2)应用场景
    • 3)vue中的观察者模式
      • 观察者(订阅者) - Watcher
      • 目标者(发布者) - Dep
      • 没有事件中心
  • 三、发布订阅模式和观察者模式的区别
    • 1)从组成分析
    • 2)从关系上分析
    • 3)从使用角度分析

前言

观察者模式和发布订阅模式作为日常开发中经常使用到的模式,我一直不能做到很好的区分。最近在看Vue的源码,里面设计到了观察者模式,比较感兴趣,就去学习了下,这里做个总结吧。

一、发布订阅模式

什么是发布订阅模式?

基于一个事件中心,接收通知的对象是订阅者,需要先订阅某个事件,触发事件的对象是发布者,发布者通过触发事件,通知各个订阅者。

举例:比如平时订阅的微信公众号,这里就涉及到两个角色:公众号(事件中心)和订阅了公众号的用户(订阅者)。当公众号的作者发布了文章之后,订阅公众号的用户就会收到消息,这里又涉及到了一个角色:公众号的作者(发布者).

应用场景

vue中的事件总线就是使用的发布订阅模式;它使用 $emit$on 进行兄弟组件通信,进行参数传递。

手动实现vue中的发布订阅模式:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue 中发布订阅模式</title>
</head>
<body><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script>  // Vue 的实例,创建事件总线let bus = new Vue()// 订阅事件bus.$on('eventName1', val => {console.log('eventName1---->', val)})bus.$on('eventName2', val => {console.log('eventName2---->', val)})// 发布事件bus.$emit('eventName1', 'eventName1')bus.$emit('eventName2', 'eventName2')}</script>
</body>
</html>

打印结果:

在这里插入图片描述

在上述代码中,bus 就是我们创建的 事件总线,它是一个 Vue 实例。我们可以在不同的组件中引入这个实例,并使用 $on 方法来监听事件,使用 $emit 方法来触发事件。通过共享同一个事件总线实例,不同组件之间可以通过事件进行通信,实现解耦。

需要注意的是,使用 事件总线模式 时要确保在适当的时候 销毁 事件总线,以避免出现 内存泄漏 的问题。可以在组件的生命周期钩子中销毁事件总线:

beforeDestroy() {bus.$off();
}

二、观察者模式

1)什么是观察者模式?

目标者对象 和 观察者对象 有相互依赖的关系,观察者对某个对象的状态进行观察,如果对象的状态发生改变,就会通知所有依赖这个对象的观察者进行更新操作。

观察者模式相比发布订阅模式少了个 事件中心

  • 目标者对象【Subject】:是被观察的对象,它维护一组观察者,并提供用于 添加、删除和通知 观察者的方法。
  • 观察者对象【Observe】:接收 Subject 状态变更通知并处理。
  • 目标者对象【Subject】状态变更时,通知所有观察者对象【Observe】进行更新操作。

2)应用场景

观察者模式在Vue中应用场景:数据响应式变化

在上一篇 Vue源码学习 - 数据响应式原理 文章中已经了解到,每个响应式属性都有 一个 dep实例 ,dep存放了依赖这个属性的 watcher(watcher是观测数据变化的函数),如果数据发生变化,dep 就会通知所有依赖它的 观察者watcher 去调用更新方法。因此,观察者需要被目标对象收集,目的是通知依赖它的所有观察者
为什么watcher中也要存放dep呢?原因是因为当前正在执行的 watcher 需要知道此时是哪个 dep 通知了自己

3)vue中的观察者模式

观察者(订阅者) - Watcher

  • update(): 当事件发生时,具体要做的事情。

目标者(发布者) - Dep

  • subs数组:存储所有的观察者。
  • addSub():添加观察者。
  • removeSub():移除观察者。
  • notify():通知观察者; 当事件发生后调用所有观察者的update()。

没有事件中心

手动实现观察者模式

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>观察者模式</title>
</head>
<body><script>// 目标者(发布者)class Dep {constructor () {// 记录所有的订阅者this.subs = []}// 添加订阅者addSub (sub) {if (sub && sub.update) {this.subs.push(sub)}}// 发布通知notify () {this.subs.forEach(sub => {sub.update()})}}// 观察者(订阅者)class Watcher {update () {console.log('update')}}//创建实例化对象 测试一下let dep = new Dep()let watcher = new Watcher()let watcher1 = new Watcher()// 添加订阅者dep.addSub(watcher)dep.addSub(watcher1)// 开启通知dep.notify()// 执行结果 update ---></script>
</body>
</html>

打印结果:触发两次更新通知。

在这里插入图片描述

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

1)从组成分析

  • 观察者模式里,只有两个角色:观察者目标者(也可以叫被观察者)。其中 被观察者 是重点。
  • 发布订阅模式里,不仅仅只有 发布者订阅者,还有一个 事件中心。其中 事件中心 是重点。
观察者模式发布订阅模式
2个角色3个角色
重点是 被观察者(目标者)重点是 事件中心

2)从关系上分析

  • 观察者和目标者,是松耦合的关系
  • 发布者和订阅者,则完全不存在耦合

3)从使用角度分析

  • 观察者模式,多用于 单个应用内部 (Vue中的数据响应式变化就是观察者模式)
  • 发布订阅模式,更多用于 跨应用的模式(比如我们常用的 消息中间件

可参考:
发布订阅模式和观察者模式

相关文章:

从Vue层面 - 解析发布订阅模式和观察者模式区别

目录 前言一、发布订阅模式什么是发布订阅模式&#xff1f;应用场景 二、观察者模式1&#xff09;什么是观察者模式&#xff1f;2&#xff09;应用场景3&#xff09;vue中的观察者模式观察者&#xff08;订阅者&#xff09; - Watcher目标者&#xff08;发布者&#xff09; - D…...

面向对象之_多态_1

目录 一. 多态 多态是什么 二. 多态的构成条件 1. 虚函数 2. 虚函数重写&#xff08;隐藏&#xff09; 3. 父类型的引用或者指针调用 4. 多态的特殊情况 1) 子类可以不加 virtual 关键字 2) 协变 三. 关键字 1. virtual 2. final 3. override 四. 多态的原理 1. 虚…...

Spring学习笔记之spring概述

文章目录 Spring介绍Spring8大模块Spring特点 Spring介绍 Spring是一个轻量级的控制反转和面向切面的容器框架 Spring最初的出现是为了解决EJB臃肿的设计&#xff0c;以及难以测试等问题。 Spring为了简化开发而生&#xff0c;让程序员只需关注核心业务的实现&#xff0c;尽…...

旧项目导入Eclipse时文件夹看起来乱七八糟,无从下手的解决办法(无main或webapp等文件夹)

首先&#xff0c;如果没有main或java/resource/webapp等文件夹&#xff0c;那就自己在src下面创建一个&#xff0c;只要对应关系与我下图左边红框一致即可&#xff0c;创建完之后java文件移到java文件夹下&#xff0c;资源文件例如.properties、老项目的数据源定义.INI文件、日…...

Reinforcement Learning with Code 【Code 2. Tabular Sarsa】

Reinforcement Learning with Code 【Code 2. Tabular Sarsa】 This note records how the author begin to learn RL. Both theoretical understanding and code practice are presented. Many material are referenced such as ZhaoShiyu’s Mathematical Foundation of Rei…...

服务调用---------Ribbon和Feign

目录​​​​​​​ 1、Ribbon 1.1 Ribbon简介 1.2 Ribbon负载均衡 负载均衡原理 负载均衡策略 Ribbon和Nginx的区别 1.3 服务调用和Ribbon负载均衡实现 2、Feign&openFeign 3、Feign支持的配置 日志功能 连接池 feign-api远程包 1、Ribbon 1.1 Ribbon简介 Ribb…...

app自动化测试之Appium问题分析及定位

使用 Appium 进行测试时&#xff0c;会产生大量日志&#xff0c;一旦运行过程中遇到报错&#xff0c;可以通过 Appium 服务端的日志以及客户端的日志分析排查问题。 Appium Server日志-开启服务 通过命令行的方式启动 Appium Server&#xff0c;下面来分析一下启动日志&#…...

婚庆服务小程序app开发方案详解

开发一款婚庆行业服务小程序有哪些功能呢&#xff1f; 1、选择分类 选择婚庆、婚车、婚宴、司仪、彩妆、婚庆用品、跟拍、摄影等&#xff0c;筛选出对应的商家 2、选择商家 选择分类后&#xff0c;可以选择商家&#xff0c;查看各个商家的详细介绍情况。 3、选择服务套餐 各…...

集合简述

集合ListArrayListLinkedList SetHashSetTreeSet MapHashMapTreeMap 集合与数组的区别 集合 集合是java中的一个容器&#xff0c;可以在里面存放数据&#xff0c;容量可以发生改变 从集合框架结构可以分析得知&#xff1a; 1、集合主要分为Collection和Map两个接口 2、Collecti…...

常见的软件测试面试题汇总

一、 你们的测试流程是怎么样的&#xff1f; 答&#xff1a;1.项目开始阶段&#xff0c;BA&#xff08;需求分析师&#xff09;从用户方收集需求并将需求转化为规格说明书&#xff0c;接 下来在项目组领导会组织需求评审。 2.需求评审通过后&#xff0c;BA 会组织项目经理…...

学习笔记|大模型优质Prompt开发与应用课(二)|第二节:超高产文本生成机,传媒营销人必备神器

文章目录 01 文字写作技能的革新&#xff0c;各行各业新机遇四大类常见文字工作新闻记者的一天新闻记者的一天–写策划prompt 新闻记者的一天–排采访prompt生成结果prompt生成结果 大模型加持&#xff0c;文字写作我们如何提效营销创作营销创作-使用预置法为不同平台生成文案p…...

Linux基础-4

1、linux高阶命令 1.1、find 在linux文件系统中&#xff0c;用来查找一个文件放在哪里了。 //举例 find /etc -name "interfaces" //总结&#xff1a; //(1)什么时候用find&#xff1f; //当你知道你要找的文件名&#xff0c;但是你忘记了它被放在哪个目录下&…...

oracle-创建函数

oracle自定义函数 核心提示&#xff1a;函数用于返回特定数据。执行时得找一个变量接收函数的返回值; 语法如下: create or replace function function_name ( argu1 [mode1]datatype1, argu2 [mode2] datatype2, … ) return datatype is begin end; 执行 var v1 varchar2(1…...

【Ansible 的脚本 --- playbook 剧本】

目录 一、playbook 剧本介绍二、示例1、运行playbook2、定义、引用变量 三、使用playbook部署lnmp集群 一、playbook 剧本介绍 playbooks 本身由以下各部分组成 &#xff08;1&#xff09;Tasks&#xff1a;任务&#xff0c;即通过 task 调用 ansible 的模板将多个操作组织在…...

ubuntu释放缓存

sudo sysctl vm.drop_caches1 sudo sysctl vm.drop_caches2 sudo sysctl vm.drop_caches3释放页面缓存&#xff1a; $ sudo sysctl vm.drop_caches1释放目录项和索引节点缓存&#xff1a; $ sudo sysctl vm.drop_caches2释放页面缓存、目录项和索引节点缓存&#xff1a; $ sudo…...

实用调试技巧(1)

什么是bug&#xff1f;调试是什么&#xff1f;有多重要&#xff1f;debug和release的介绍。windows环境调试介绍。一些调试的实例。如何写出好&#xff08;易于调试&#xff09;的代码。编程常见的错误。 什么是Bug 我们在写代码的时候遇到的一些问题而导致程序出问题的就是Bu…...

uniapp:H5定位当前省市区街道信息

高德地图api&#xff0c;H5定位省市区街道信息。 由于uniapp的uni.getLocation在H5不能获取到省市区街道信息&#xff0c;所以这里使用高德的逆地理编码接口地址接口&#xff0c;通过传key和当前经纬度&#xff0c;获取到省市区街道数据。 这里需要注意的是&#xff1a;**高德…...

自然语言处理从入门到应用——LangChain:提示(Prompts)-[提示模板:部分填充的提示模板和提示合成]

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 部分填充的提示模板 提示模板是一个具有.format方法的类&#xff0c;它接受一个键值映射并返回一个字符串&#xff08;一个提示&#xff09;&#xff0c;以传递给语言模型。与其他方法一样&#xff0c;将提示模板进行…...

论文笔记--GloVe: Global Vectors for Word Representation

论文笔记--GloVe: Global Vectors for Word Representation 1. 文章简介2. 文章概括3 文章重点技术3.1 两种常用的单词向量训练方法3.2 GloVe3.3 模型的复杂度 4. 文章亮点5. 原文传送门6. References 1. 文章简介 标题&#xff1a;GloVe: Global Vectors for Word Representa…...

day57|● 647. 回文子串 ● 516.最长回文子序列

647. 回文子串 https://leetcode.cn/problems/palindromic-substrings/solution/by-lfool-2mvg/ Given a string s, return the number of palindromic substrings in it. A string is a palindrome when it reads the same backward as forward. A substring is a contiguous…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...