观察者(Observer)模式

news2024/11/26 2:40:10

目录

  • 使用场景
  • 参与者
  • 协作
  • 效果
  • 实现
  • 类图

观察者(Observer)又被称为 发布-订阅模式,是一种对象行为模式,定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时所有依赖于它的对象都得到通知并自动更新。通知的发布者(目标)发出通知时并不需要知道谁是它的观察者。可以有任意数量的观察者订阅并接收通知。

使用场景

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面,将这二者封装在独立的对象中以使他们可以各自独立地改变和复用
  • 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象要改变
  • 当一个对象必须通知其他对象,而它又不能假定其他对象是谁,换言之,你不希望这些对象是紧密耦合的

参与者

  • Subject(目标):
    • 目标知道它的观察者,可以有任意多个观察者观察同一个目标
    • 提供注册和删除观察者对象的接口
  • Observer(观察者):为那些在目标发生改变时需要获得通知的对象定义一个更新接口
  • ConcreteSubject(具体目标):
    • 将有关状态存入各ConcreteObserver对象
    • 当它的状态发生改变时,向它的各个观察者发出通知
  • ConcreteObserver(具体观察者)
    • 维护一个指向ConcreteSubject对象的引用——需要这个引用做什么?在哪些场合下在Observer中需要用到Subject对象?
    • 存储有关状态,这些状态应与目标的状态保持一致
    • 实现Observer的更新接口以使自身状态与目标状态保持一致

协作

  • ConcreteSubject发生任何可能导致其观察者状态不一致的改变时,它将通知到它的各个观察者
  • 在得到一个具体目标的改变通知后,ConcreteObserver对象可向目标对象查询信息(这一步有什么意义)。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致
  • 注意:
    • 发出改变请求的Observer对象并不立即更新,而是将其推迟到它从目标得到一个通知之后。
    • Notify不总是由目标对象调用,它也可被一个观察者或其他对象调用

效果

Observer模式允许你独立的改变目标和观察者,可与单独复用目标对象而无需同时复用其观察者,反之亦然。它也可以在不改动目标和其他观察者的前提下增加观察者。

  • 目标和观察者之间的抽象耦合。一个目标仅仅知道它有一系列观察者,每个都符合抽象的Observer类的接口,目标和观察者之间的耦合是抽象的和最小的
  • 支持广播通信。目标对象不关心有多少对象对自己关心,它唯一的责任就是通知它的各个观察者;处理还是忽略一个通知取决于观察者
  • 意外的更新:因为一个观察者并不知道其他观察者的存在,他可能对改变目标的最终代价一无所知,因此可能会造成问题

实现

  • 创建目标到其观察者之间的映射
    • 最简单的方法是显式的在目标中保存对观察者的引用,但当目标很多而观察者较少时这样的存储代价太高
    • 用时间换空间:用一个关联查找机制来维护目标到观察者的映射——待实现
  • 观察多个目标:某些情况下一个观察者依赖多个目标可能是有意义的,例如一个表格对象可能依赖于多个数据源——多个目标时应该需要区分是哪个目标发出的通知
  • 谁触发更新:
    • 由目标对象的状态设定操作在改变目标对象的状态后自动调用Notify。这种方法的优点是不需要客户调用Notify,缺点是连续的操作会产生多次连续的更新,可能效率会比较低,目前大部分都是用这种方式通知
    • 客户负责调用Notify,优点是客户可以在一系列的状态完成后再一次性触发更新,避免了不必要的中间更新;缺点是给客户增加了触发更新的责任
  • 对已删除目标的悬挂引用。删除一个目标时应注意不要在其观察者中遗留对该目标悬挂引用。一种避免悬挂引用的方法是当一个目标被删除时,让它通知它的观察者将对该目标的引用复位。一般来说不能简单地删除观察者,因为其他对象可能会引用它们
  • 在发出通知前确保目标的状态自身是一致的。因为观察者在更新其状态的过程中需要查询目标的当前状态。当Subject的子类调用继承的该项操作时很容易无意中违反这条自身一致原则
  • 避免特定于观察者的更新协议—推/拉模型:广播出去的信息量可能很大,也可能很少
    • 推模型:目标向发送者发送关于改变的详细信息,而不管他们是否需要;
      • 推模型假定目标知道一些观察者的需要的信息
      • 推模型可能使得观察者相对难以复用
    • 拉模型:目标除了最小通知外什么也不送出,而在此之后由观察者显式的向目标询问细节。
      • 拉模型强调的是目标不知道它的观察者
      • 拉模型可能效率较差,因为观察者对象需在没有目标对象帮助的情况下确定什么改变了
  • 显式的指定感兴趣的改变:可以扩展目标的注册接口让各观察者注册仅对特定事件感兴趣
  • 封装更复杂的语义:当目标和观察者间的依赖关系特别复杂时可能需要一个维护这些关系的对象,称这样的对象为更改管理器,它的目的是尽量减少观察者反映其目标的状态变化所需的工作量。三个责任:
    • 将一个目标映射到它的观察者并提供一个接口来维护这个映射,这就不需要由目标来维护对其观察者的引用,反之亦然
    • 它定义一个特定的更新策略
    • 根据一个目标的请求,更新所有依赖于这个目标的观察者
  • 谁来向目标注册观察者?可以是客户,也可以是Observer,书中的例子是Observer

类图

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

校园跑腿小程序都包括哪些业务呢?

校园创业,大家都知道,一直以来是个非常火热的话题,每位步入大学校园的学子们都有过在校创业的想法,包括我们一些有着学校资源的社会创业者们,早已经看好了中国高校这块巨大的市场。 在这里,我要跟大家分享…

面向对象进阶二(包、final、权限修饰符、代码块、abstract、接口、内部类)

面向对象进阶二 一、包、final、权限修饰符、代码块1.1 包1.2 final关键字1.3 权限修饰符1.4 代码块1.4.1 局部代码块(已淘汰,了解)1.4.2 构造代码块(了解内容)1.4.3 静态代码块 二、抽象方法和抽象类三、接口3.1 接口…

解释 void 类型转换: (void)++y

谢谢大师们的指导,保存,分享

【LeetCode】HOT 100(23)

题单介绍: 精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

JS语法学习实战系列

JS学习实战系列 一、数据类型二、运算符三、流程控制四、let 、var、 const 声明变量的区别 JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它…

电路维修(双端队列bfs)

题意:从左上角走到右下角,且只能走斜线,斜线可以旋转,旋转斜线那么走过这条线,那么距离就加1,求最小的距离。 分析:有一个性质,因为起点是偶数点(0,0),那么它只能走到偶数点&#x…

进程间通信-有名管道

理解&#xff1a;有名管道类似于文件io 相当于新建一个管道文件作为中间介质 进行数据的交换&#xff08;因此可以不同线程间通信&#xff09; 写入管道文件 #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #…

菜鸡shader:L9 屏幕UV及屏幕UV扰动

文章目录 屏幕UV代码最后效果 屏幕UV扰动代码最后效果 屏幕UV 最主要的代码是屏幕UV的获取&#xff1a; 这里具体可以参考这位大佬的博客&#xff1a; 个人学习笔记——庄懂的技术美术入门课&#xff08;美术向&#xff09;17&#xff08;VS空间畸变矫正的原理&#xff09;个…

驱动程序设计 Linux设备驱动中的阻塞与非阻塞IO、信号与函数 7.12

linux设备驱动中的阻塞与非阻塞I/O 阻塞&#xff1a;等待某种资源&#xff0c;如果获取不到&#xff0c;就会把当前任务挂起&#xff0c;等待资源准备好 1. int flag 0; while(flag 0); 2.等待队列 wait_event(q,flag > 0); wakeup(q);非阻塞&#xff1a;等待某种资源非…

nodejs中使用Redis

安装教程&#xff1a;Redis 安装 | 菜鸟教程 redis下载链接&#xff1a;Release Redis for Windows 5.0.14.1 tporadowski/redis GitHub解压双击redis-server.exe启动服务器端双击redis-cil.exe启动客户端连接服务端在客户端看看能不能ping通 完成 遇到的问题1&#x…

前端处理后端返回的文件流,进行文件下载

二进制流格式 Blob格式 前言&#xff1a; 需求&#xff1a;根据后端接口返回的文件流进行数据处理&#xff0c;并实现文件的下载&#xff0c;且下载文件为word文档. 代码实现&#xff1a; //下载文件 async function DownLoadFile(row) {let res await DownLoadFileAPI(row.…

火山引擎 DataLeap 构建Data Catalog系统的实践(二):技术与产品概览

技术与产品概览 架构设计 元数据的接入 元数据接入支持T1和近实时两种方式 上游系统&#xff1a;包括各类存储系统&#xff08;比如Hive、 Clickhouse等&#xff09;和业务系统&#xff08;比如数据开发平台、数据质量平台等&#xff09; 中间层&#xff1a; ETL Bridge&#x…

PCL点云处理之最小二乘直线拟合(❤❤❤亲测可用❤❤❤)(二百)

PCL点云处理之最小二乘直线拟合(❤❤❤亲测可用❤❤❤)(二百) 一、算法介绍二、具体代码1.代码2.结果一、算法介绍 点云近似于直线分布,但相对要散乱一些,此时,最小二乘直线拟合,是一种最常用的拟合方法,可以从中找到最优的直线方程,用于描述点云的分布情况。网上介…

Yjmstr的算法竞赛模板(updating)

YJMSTR的算法竞赛模板 目录 文章目录 YJMSTR的算法竞赛模板目录图论一、最短路1.spfa与负环、最短路1.1 bfs-spfa找负环&#xff1a;1.2 dfs-spfa找负环1.3 spfa求最短路的优化 2.dijkstra模板&#xff08;set模拟二叉堆堆优化)2.1有向图最小环 3.Floyd求多源最短路/传递闭包/…

ARM Coresight 系列文章 7 - ARM Coresight 通过 AHB-AP 访问 cpu 内部 coresight 组件

文章目录 如下图所示&#xff0c;如果A78想去访问M33的内部 coresight 组件 ETM&#xff0c;需要要怎么做&#xff1f; 答案也正是在图中&#xff0c;首先A78 通过AXI 互联&#xff0c;接入到 APBIC 的 slave port&#xff0c;再通过APBIC 的 master 送出&#xff0c;而APBIC中…

【win11】将一个程序设置为开机启动

Windows 在 Windows 系统中&#xff0c;可以通过在 “启动” 文件夹中放置程序的快捷方式来实现开机启动。 按照以下步骤操作&#xff1a; 按 Win R 打开 “运行” 对话框&#xff0c;输入 shell:startup&#xff0c;然后按回车。这将打开 “启动” 文件夹。 找到你想设置…

自由视点合成中的表征学习(二)

三维重建以及神经渲染中的学习 公众号AI知识物语 本文内容为参加过去一次暑期课程学习时的笔记&#xff0c;浅浅记录下。 自由视点合成中的表征学习 目标&#xff1a;给定单一场景多个图片以及相机位子&#xff0c;生成新视角下的图像 挑战&#xff1a;恢复三维场景结构&…

Stable Diffusion (持续更新)

引言 本文的目的为记录stable diffusion的风格迁移&#xff0c;采用diffusers example中的text_to_image和textual_inversion目录 2023.7.11 收集了6张水墨画风格的图片&#xff0c;采用textual_inversion进行训练&#xff0c;以"The street of Paris, in the style of …

rabbitmq 开启 virtual host

由于我的rabbitmq架设在测试服务期。 导致我本地测试的mq消息&#xff0c;经常被服务器消费掉。 所以通过添加v-host&#xff0c;可以创建专属v-host域下的消息进行生产和消费。 一 新增用户 点击Admin,点击右边Users 输入Username Password &#xff0c;并且Tags给与Admin权…