设计模式(行为型)-观察者模式

目录

定义

类图

角色

Subject:抽象主题(抽象被观察者)​

ConcreteSubject:具体主题(具体被观察者)​

Observer:抽象观察者​

ConcrereObserver:具体观察者​

优缺点

优点​

缺点​

使用场景

代码示例

总结


定义

        观察者模式定义了对象间的一种一对多的依赖关系,当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象(观察者)都将得到通知并被自动更新。这种模式又被称为发布 - 订阅(Publish/Subscribe)模式。它使得被观察者和观察者之间实现了松耦合,被观察者无需知道具体的观察者是谁,只需专注于自身状态的变化,而观察者则专注于对状态变化的响应。​

        例如,在一个新闻发布系统中,新闻机构是被观察者,而众多订阅该新闻机构的用户则是观察者。当新闻机构发布了一条新的新闻(状态改变),所有订阅的用户都会收到通知并更新自己的新闻列表(自动更新)。

类图

角色

  • Subject:抽象主题(抽象被观察者)​
  • 抽象主题角色负责管理所有观察者对象,它将所有观察者对象保存在一个集合里。每个主题都可以拥有任意数量的观察者。抽象主题提供了增加和删除观察者对象的接口,这样观察者可以动态地注册和注销对主题的观察。例如,在一个图形绘制系统中,图形对象可以作为抽象主题,而对图形状态感兴趣的各种监听器就是观察者。图形对象提供了添加和移除监听器的方法。​

  • ConcreteSubject:具体主题(具体被观察者)​
  • 具体主题是抽象主题的具体实现。它负责将有关状态存入具体观察者对象。当具体主题的内部状态发生改变时,它会给所有注册过的观察者发送通知。比如在一个股票交易系统中,股票对象就是具体主题,当股票价格发生变化(内部状态改变)时,它会通知所有关注该股票的投资者(观察者)。​

  • Observer:抽象观察者​
  • 抽象观察者是所有具体观察者的抽象类。它定义了一个更新接口,当观察者得到主题更改通知时,将通过这个接口来更新自己。例如,在一个天气监测系统中,各种显示天气信息的组件都可以看作是观察者,它们都实现了抽象观察者定义的更新接口,以便在天气数据(主题)发生变化时更新自己的显示内容。​

  • ConcrereObserver:具体观察者​
  • 具体观察者实现了抽象观察者定义的更新接口。在得到主题更改通知时,具体观察者会根据通知内容更新自身的状态。比如在一个社交媒体平台中,用户的个人页面就是具体观察者,当用户发布了新动态(主题状态改变),关注该用户的其他用户的页面(具体观察者)会通过更新接口获取新动态并更新显示。

优缺点

优点​

  • 实现了观察者和被观察者之间的抽象耦合:被观察者只需要关注自身状态的变化,而无需关心具体的观察者是谁以及如何处理状态变化。观察者也只需实现统一的更新接口,不依赖于被观察者的具体实现。这使得系统的扩展性和维护性大大提高。例如,在一个游戏开发中,游戏角色(被观察者)的状态变化可以通知各种不同的游戏元素(观察者),如场景特效、音效等,而游戏角色无需知道这些具体的观察者细节。​

  • 动态联动:观察者可以根据需要动态地注册和注销对主题的观察。这意味着系统可以根据运行时的需求灵活地调整观察者和被观察者之间的关系。比如在一个实时监控系统中,新的监控设备(观察者)可以随时接入系统并开始观察特定的被监控对象(主题),而当设备故障或不再需要时也可以方便地注销。​

  • 广播通信:被观察者会向所有登记的观察者发出通知,这种广播机制使得信息能够高效地传播给所有相关的对象。在一个分布式系统中,一个节点(被观察者)的状态变化可以通过观察者模式快速通知到其他相关节点(观察者),实现系统的一致性和协同工作。​

缺点​

  • 开发和调试复杂性:在应用观察者模式时,由于程序中包括一个被观察者和多个观察者,开发和调试的难度会增加。需要仔细处理观察者的注册、注销以及通知的顺序等问题,否则可能会出现意想不到的错误。例如,在一个大型电商系统中,订单状态的变化(被观察者)会通知多个模块(观察者),如库存管理、物流配送等,对这些复杂关系的调试需要花费更多的时间和精力。​

  • 运行效率问题:当观察者数量众多时,每次被观察者状态改变都要通知所有观察者,可能会导致性能下降。特别是在通知过程中如果存在复杂的业务逻辑,这种影响会更加明显。比如在一个社交网络平台中,一个热门用户的动态更新(被观察者)可能会通知成千上万的粉丝(观察者),如果处理不当,可能会造成系统响应变慢。此外,在一些编程语言中,消息通知默认是顺序执行的,一个观察者的卡顿会影响整体的执行效率。

使用场景

  • 关联行为场景:当系统中存在多个对象之间存在关联行为,且这些行为是可拆分的,而不是 “组合” 关系时,适合使用观察者模式。例如,在一个音乐播放软件中,播放列表(被观察者)的变化(如添加、删除歌曲)会同时影响播放进度条、歌曲信息显示等多个组件(观察者),这些组件的行为是相互关联但又可独立变化的。​

  • 事件多级触发场景:在一些复杂的业务场景中,一个事件的发生可能会触发一系列的后续事件,观察者模式可以很好地处理这种多级触发的情况。比如在一个工作流管理系统中,任务状态的改变(被观察者)可能会触发审批流程、通知相关人员等多个后续事件(观察者),这些事件又可能进一步触发其他事件。​

  • 跨系统的消息交换场景:如消息队列、事件总线的处理机制中,观察者模式被广泛应用。不同的系统可以作为观察者订阅特定的消息主题(被观察者),当主题有新消息发布时,订阅的系统会收到通知并进行相应处理。例如,在一个微服务架构的电商系统中,订单服务(被观察者)可以通过消息队列向库存服务、支付服务等多个其他服务(观察者)发送订单状态变化的消息。

代码示例

        以下是一个使用 Java 语言实现观察者模式的简单示例:

import java.util.ArrayList;
import java.util.List;// 抽象主题
abstract class Subject {private List<Observer> observers = new ArrayList<>();public void attach(Observer observer) {observers.add(observer);}public void detach(Observer observer) {observers.remove(observer);}public void notifyObservers() {for (Observer observer : observers) {observer.update(this);}}public abstract int getState();
}// 具体主题
class ConcreteSubject extends Subject {private int state;public int getState() {return state;}public void setState(int state) {this.state = state;notifyObservers();}
}// 抽象观察者
interface Observer {void update(Subject subject);
}// 具体观察者
class ConcreteObserver implements Observer {private int observerState;@Overridepublic void update(Subject subject) {observerState = ((ConcreteSubject) subject).getState();System.out.println("观察者状态更新为: " + observerState);}
}

        在上述代码中,Subject类是抽象主题,定义了添加、删除观察者以及通知观察者的方法。ConcreteSubject是具体主题,实现了Subject的抽象方法,并在状态改变时通知观察者。Observer是抽象观察者接口,定义了更新方法。ConcreteObserver是具体观察者,实现了Observer接口的更新方法,根据主题的状态更新自身状态。

        通过以下测试代码可以验证观察者模式的运行:

public class Main {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject();ConcreteObserver observer = new ConcreteObserver();subject.attach(observer);subject.setState(10);}
}

        当subject的状态被设置为 10 时,会自动通知observer,observer会更新自身状态并输出相应信息。

总结

        观察者模式作为一种强大的设计模式,通过定义对象间的一对多依赖关系,实现了对象之间的解耦,提高了系统的灵活性和可维护性。尽管在应用过程中需要注意开发和调试的复杂性以及运行效率问题,但在合适的场景下,观察者模式能够极大地提升软件系统的质量和可扩展性。无论是在小型应用还是大型分布式系统中,观察者模式都有着广泛的应用前景,是开发者在软件设计过程中不可或缺的工具之一。希望通过本文的介绍,读者能够对观察者模式有更深入的理解,并在实际项目中灵活运用这一模式。​

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

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

相关文章

调用华为云API实现口罩识别

1.作者介绍 范小雨&#xff0c;女&#xff0c;西安工程大学电子信息学院&#xff0c;2024级研究生 研究方向&#xff1a;机器视觉与人工智能 电子邮件&#xff1a;1019044907qq.com 高金年&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2024级研究生&#…

C++中的单例模式及具体应用示例

AI 摘要 本文深入探讨了C中的单例模式及其在机器人自主导航中的应用&#xff0c;特别是如何通过单例模式来管理地图数据。文章详细介绍了单例模式的基本结构、优缺点以及在多线程环境中的应用&#xff0c;强调了其在保证数据一致性和资源管理中的重要性。 接着&#xff0c;文章…

【STM32】从新建一个工程开始:STM32 新建工程的详细步骤

STM32 开发通常使用 Keil MDK、STM32CubeMX、IAR 等工具来创建和管理工程。此处是 使用 Keil MDK5 STM32CubeMX 创建 STM32 工程的详细步骤。 新建的标准库工程文件已上传至资源中&#xff0c;下载后即可直接使用。 标准库新建 STM32 工程的基本目录结构&#xff1a;STD_STM…

Java 大视界 -- 基于 Java 的大数据实时流处理中的窗口操作与时间语义详解(135)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

Fastdata极数:中国民宿行业发展趋势报告2025

2024年&#xff0c;中国游客出行次数大幅上涨&#xff0c;旅游相关支出也复苏强劲。2025年中国旅游业还将持续稳健的复苏及增长。同时&#xff0c;中国旅游业将见证一场深刻的变革&#xff0c;这场变革的推动力是消费者对旅游期望的转变&#xff0c;经济因素和年轻人全新价值观…

【自定义微信小程序拉下选择过滤组件】searchable-select

【自定义微信小程序拉下选择过滤组件】searchable-select 组件说明 点击输入框获取焦点&#xff0c;输入内容&#xff0c;自动匹配搜索结果&#xff0c;点击搜索结果&#xff0c;自动填充搜索结果。 组件使用 将组件文件夹放在项目中。在需要使用的页面的json文件中&#x…

推理大模型的后训练增强技术-Reasoning模型也进化到2.0了,这次居然学会用工具了

论文题目&#xff1a;START: Self-taught Reasoner with Tools 论文链接&#xff1a;https://arxiv.org/pdf/2503.04625 论文简介 Reasoning模型也进化到2.0了&#xff0c;这次居然学会用工具了&#xff01;✨ 最近有个叫START的方法&#xff0c;让大模型也能学着用工具&#…

Idea集成docker通过ca加密实现镜像打包

​ Idea集成docker实现镜像打包_ideadocker镜像打包-CSDN博客 ​ 之前通过这种方式虽然可以实现idea通过maven打jar包的同时把docker镜像也进行打包&#xff0c;但是这种方式存在很大漏洞&#xff0c;就是服务器的2375端口大开&#xff0c;任何人拿着idea通过这种方式都可以连…

SOC与电压的关系

与电池相关的参数都与SOC有关&#xff0c;也就是电池剩余容量的百分比即荷电状态。 SOC百分之二十时&#xff0c;对应3.2V,SOC80&#xff05;时对应3.3V。

塔能科技:做节能界的“催化剂”,加速工厂能源改造变革

在全球坚定不移地迈向可持续发展的宏大进程中&#xff0c;节能降耗早已从一种发展理念&#xff0c;深度融入到经济社会发展的每一个脉络之中&#xff0c;成为企业在激烈市场竞争中实现降本增效的核心策略&#xff0c;更是推动整个社会朝着绿色、低碳、循环方向转型的关键支撑点…

【算法学习之路】11.并查集

并查集 前言一.简介二.基础并查集三.基础并查集题目12 四.种类并查集&#xff08;扩展域并查集&#xff09;五.种类并查集的题目 前言 我会将一些常用的算法以及对应的题单给写完&#xff0c;形成一套完整的算法体系&#xff0c;以及大量的各个难度的题目&#xff0c;目前算法也…

【微服务】SpringBoot整合LangChain4j 操作AI大模型实战详解

目录 一、前言 二、Langchain4j概述 2.1 Langchain4j 介绍 2.1.1 Langchain4j 是什么 2.1.2 主要特点 2.2 Langchain4j 核心组件介绍 2.3 Langchain4j 核心优势 2.4 Langchain4j 核心应用场景 三、SpringBoot 整合 LangChain4j 组件使用 3.1 前置准备 3.1.1 获取apik…

【图片批量转换合并PDF】多个文件夹的图片以文件夹为单位批量合并成一个PDF,基于wpf的实现方案

项目背景: 多个图片分布在不同文件夹,如何以文件夹为单位批量合并成一个PDF,还要保证文件夹里面图片大小和顺序 实现功能: 1、单张图片的转换PDF:一张图临时转一下 2、多张图片转换成PDF:多张图单独转成PDF 3、多级目录多张图转换成PDF:多级目录多张图单独转成多个PDF…

因果推荐|可解释推荐系统的反事实语言推理

论文&#xff1a;https://arxiv.org/pdf/2503.08051 代码&#xff1a;GitHub - kylokano/CausalX 很新的论文&#xff0c;南大五天前挂到arxiv的&#xff0c;代码基于Recbole&#xff0c;没给全但是提供了足够的验证。 1 动机 可解释推荐不仅提供高质量的推荐&#xff0c;而…

Zabbix安装(保姆级教程)

Zabbix 是一款开源的企业级监控解决方案,能够监控网络的多个参数以及服务器、虚拟机、应用程序、服务、数据库、网站和云的健康状况和完整性。它提供了灵活的通知机制,允许用户为几乎任何事件配置基于电子邮件的告警,从而能够快速响应服务器问题。Zabbix 基于存储的数据提供…

【spring boot 实现图片验证码 前后端】

导入hutool依赖 <!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.36</version>获取验证码接口 Autowiredprivate Captcha captcha;private final static Long VALIDA…

arthas基础命令

文章目录 1. help2. cat3. grep4. pwd5. cls6. session7. reset8. version9. history10. quit11. stop12. keymapArthas 命令行快捷键后台异步命令相关快捷键小结 1. help 作用&#xff1a;查看命令帮助信息 2. cat 作用&#xff1a;打印文件内容&#xff0c;和linux里的cat命…

痉挛性斜颈护理宝典:重拾生活平衡

痉挛性斜颈会给患者的生活带来诸多不便&#xff0c;有效的健康护理对缓解症状、提升生活质量十分关键。 在日常活动方面&#xff0c;患者应保持正确的姿势。站立和坐姿要挺直脊背&#xff0c;避免长时间低头或歪头&#xff0c;减少颈部肌肉的额外负担。睡眠时&#xff0c;选择高…

虚拟定位 1.2.0.2 | 虚拟定位,上班打卡,校园跑步模拟

Fake Location是一款运行于安卓平台上的功能强大、简单实用的虚拟定位软件。它能够帮助用户自定义位置到地图上的任意地方&#xff0c;以ROOT环境运行不易被检测&#xff0c;同时也支持免ROOT运行。提供路线模拟、步频模拟、WIFI模拟等方式&#xff0c;支持反检测。 大小&…

C++基础 [五] - String的模拟实现

目录 前言 string类的模拟实现 成员函数的实现 构造函数 拷贝构造函数 赋值运算符重载 析构函数 元素访问的实现 operator[ ] Iterator - 迭代器 容量大小的实现 size capacity reserve ​编辑resize 内容修改的实现 push_back append operator(char ch) …