掌握设计模式--观察者模式

news/2025/1/18 10:54:37/文章来源:https://www.cnblogs.com/dennyLee2025/p/18676232

观察者模式(Observer Pattern)

观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象间的一对多依赖关系,使得当一个对象状态发生改变时,所有依赖于它的对象都会自动收到通知并更新。

主要组成部分

主题(Subject):主题是被观察的对象,它维护一个观察者列表。当它的状态发生改变时,会通知所有的观察者。主题提供方法来注册、注销观察者。

观察者(Observer):观察者是依赖于主题的对象,它会在主题状态发生变化时收到通知,进而更新自身的状态。观察者有一个更新方法,当主题状态变化时,主题会调用此方法来通知观察者。

工作流程

  1. 注册观察者:观察者通过主题提供的注册方法将自己注册到主题上。
  2. 状态变化:主题的状态发生变化时,它会遍历其所有注册的观察者。
  3. 通知观察者:主题调用每个观察者的更新方法,通知它们进行状态更新。
  4. 更新观察者:观察者根据通知更新自己的状态,通常会重新渲染界面或进行其他的状态更新。

案例实现

假设有一个温度监控系统:

  • 主题:温度传感器,当温度发生变化时,它会通知所有依赖于它的观察者。
  • 观察者:可以是不同的显示设备或报警系统,温度变化时,它们会根据新温度执行相应操作。

案例类图

image

观察者接口

用于观察温度变化的接口,订阅的主题发生变化时,通过观察者接口的update方法来通知订阅了的所有观察者。

interface Observer {void update(int temperature);
}

观察者实现类

// 观察者实现类1
class DisplayDevice implements Observer {@Overridepublic void update(int temperature) {System.out.println("显示装置:温度更新到" + temperature);}
}// 观察者实现类2
class AlarmSystem implements Observer {@Overridepublic void update(int temperature) {if (temperature > 42) {System.out.println("警报:温度超过阈值!");}}
}

主题类(被观察者)

class TemperatureSensor {// 观察者列表private List<Observer> observers = new ArrayList<>();private int temperature;// 注册观察者public void addObserver(Observer observer) {observers.add(observer);}// 移除观察者public void removeObserver(Observer observer) {observers.remove(observer);}// 设置温度并通知观察者public void setTemperature(int temperature) {this.temperature = temperature;notifyObservers();}// 通知所有观察者private void notifyObservers() {for (Observer observer : observers) {observer.update(temperature);}}
}

测试客户端

public class ObserverPatternDemo {public static void main(String[] args) {// 创建主题和观察者TemperatureSensor sensor = new TemperatureSensor();Observer display = new DisplayDevice();Observer alarm = new AlarmSystem();// 注册观察者:如果没注册,那就不会通知sensor.addObserver(display);sensor.addObserver(alarm);// 改变主题的状态sensor.setTemperature(45);sensor.setTemperature(28);}
}

测试输出结果

显示装置:温度更新到45

警报:温度超过阈值!

显示装置:温度更新到28

优缺点和使用场景

优点

  1. 松耦合:观察者与主题之间是松耦合的,主题不需要知道具体的观察者,观察者也不需要了解主题的内部实现。
  2. 动态添加或删除观察者:可以在运行时动态地添加或删除观察者。

缺点

  1. 多次更新:如果有大量观察者,状态变化可能导致多次调用更新方法,性能可能受到影响。
  2. 循环依赖:观察者之间如果互相通知更新,可能引起循环依赖或无限循环。

观察者模式是处理事件驱动系统或需要多个对象同步更新状态的常用模式,尤其在分布式系统、GUI框架中应用广泛。

适用场景

  • 事件驱动的系统:例如GUI框架(按钮点击、界面更新等)、消息通知系统等。
  • 发布-订阅系统:如消息队列系统、新闻订阅、社交媒体更新等。
  • 数据同步:多个模块需要同步更新某些共享数据时,如温度监控、股票价格变化等。

观察者模式的应用

Spring的事件机制ApplicationEvent是事件对象,ApplicationListener是事件监听器,当ApplicationEvent发布时,所有注册了该事件类型的ApplicationListener会被通知并处理该事件。ApplicationEventPublisher接口(通常是ApplicationContext的实现类)作为被观察者,ApplicationListener作为观察者。事件的发布和监听实现了松耦合的通知机制。

Java Web中的监听器,它通过监听和响应Web应用的生命周期事件、HTTP会话事件、请求事件以及属性变化事件。常见的监听器接口包括ServletContextListenerHttpSessionListenerServletRequestListener等,实现相应的监听接口,即可完成相应事件的监听。监听器机制的使用可以帮助开发者在特定事件发生时执行一些处理逻辑,保证代码的解耦和灵活性。

总结

观察者模式是一种行为设计模式,其核心在于通过定义一对多的依赖关系,使得当被观察者的状态发生变化时,所有依赖的观察者自动收到通知并更新,从而实现对象之间的松耦合和动态响应,同时便于观察者的扩展。

image

需要查看往期设计模式文章的,可以在个人主页中或者文章开头的集合中查看,可关注我,持续更新中。。。


超实用的SpringAOP实战之日志记录

2023年下半年软考考试重磅消息

通过软考后却领取不到实体证书?

计算机算法设计与分析(第5版)

Java全栈学习路线、学习资源和面试题一条龙

软考证书=职称证书?

软考中级--软件设计师毫无保留的备考分享

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

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

相关文章

[docker逃逸] Privileged 特权模式逃逸复现

本文作者CVE-柠檬i CSDN:https://blog.csdn.net/weixin_49125123 博客园:https://www.cnblogs.com/CVE-Lemon 微信公众号:Lemon安全 简述 在 Docker 中,Privileged 特权模式赋予容器几乎与宿主机相同的权限,允许其访问所有设备和内核功能。这种模式虽然提供了灵活性,但也…

GaussDB实时分析组件

云原生数据库以OLTP为主,同时也支持基于OLTP数据的OLAP需求,如每日报表。在云原生数据库中,DBA可以选择为这部分表创建列存索引。创建完列存索引之后,执行器在做顺序扫描的时候,会自动选择列存索引进行数据的读取,实现快速扫描计算的能力。 云原生数据库以行存为基础,数…

GaussDB关键技术方案_通信组件

GaussDB关键技术方案_通信组件 云原生数据库采用shared disk架构,各个计算节点对等,计算节点之间通过页面交换实现缓存数据的一致性,为了提高页面传递的效率,需要利用RDMA或UB单边读写的能力;云原生数据库为了管理动态资源,需要对动态资源的owner分配进行加锁,分布式锁管…

arch linux使用qemu创建和使用一个win7镜像

安装qemu sudo pacman -S qemu 创建虚拟硬盘 qemu-img create -f qcow2 disk.img 10G (其中10G表示硬盘大小。) 启动虚拟机 qemu-system-x86_64 -enable-kvm -m 2048 -hda disk.img -cdrom your_iso.iso (-enable-kvm启用KVM加速,-m 2048设置内存大小为2048MB,your_iso.is…

一款基于 .NET8 + Vue 开源、免费、跨平台的企业级在线考试系统

前言 今天大姚给大家分享一款基于 .NET8 + Vue 开源、免费(AGPL-3.0开源协议)、跨平台的企业级在线考试系统:XBLMS。 项目介绍 XBLMS是一款基于 .NET8 + Vue 开源、免费(AGPL-3.0开源协议)、跨平台的企业级在线考试系统,系统支持多种数据库系统,包括人大金仓、达梦、Oce…

Typora Markdown编辑器

Typora Markdown编辑器 Typora for Mac是一款功能丰富、界面简洁优雅的Markdown编辑器,它既简单易用,又具有丰富的功能。无论您是写作爱好者还是专业人士,Typora都能帮助您提高写作效率,制作出清晰、专业的文档。

在Mac上快速运行Windows软件,玩黑神话悟空、办公-CrossOver

CrossOver 在Mac上快速运行Windows软件-安装 CrossOver 可以在 Mac 上运行成千上万的 Windows 程序。从办公软件、实用工具、游戏到设计软件,只需在 Mac 的 dock 轻按一下便可运行。您可以 Windows 程序和 Mac 程序之间随意切换,而这一切无需重启、无需虚拟机,也无需购买 Wi…

MAC|win——NTFS和APFS文件系统

问题:2T的Windows机械硬盘+读写器+转接头,连接到Mac,能读取机械硬盘里的内容,但是,无法写入(新建目录、写入文件)。 答案: NTFS(New Technology File System)和APFS(Apple File System)分别是微软和苹果推出的文件系统,它们在设计理念、性能、兼容性和应用场景上各…

Synfig Studio 1.5 (Linux, macOS, Windows) - 开源 2D 动画软件

Synfig Studio 1.5 (Linux, macOS, Windows) - 开源 2D 动画软件Synfig Studio 1.5 (Linux, macOS, Windows) - 开源 2D 动画软件 Open-source 2D Animation Software 请访问原文链接:https://sysin.org/blog/synfig-studio/ 查看最新版。原创作品,转载请保留出处。 作者主页…

LibreOffice 24.8 (Linux, macOS, Windows) - 自由免费的全能办公套件

LibreOffice 24.8 (Linux, macOS, Windows) - 自由免费的全能办公套件LibreOffice 24.8 (Linux, macOS, Windows) - 自由免费的全能办公套件 professional FREE and open source painting program 请访问原文链接:https://sysin.org/blog/libreoffice/ 查看最新版。原创作品,…

UWP 部署失败 DEP0700 0x80073CF0 错误 0x800701C0 从位置 AppxManifest.xml 中打开文件失败

具体的错误内容如下 DEP0700: 应用程序注册失败。[0x80073CF0] 错误 0x800701C0: 从位置 AppxManifest.xml 中打开文件失败,错误为: 无法遍历该路径,因为它包含不受信任的装入点。 对应的英文版错误大概内容如下 DEP0700: Registration of the app failed. [0x80073CF0] erro…

【ChatGPT】Mr. Ranedeer 个性化学习定制

Mr. Ranedeer 是ChatGPT 的一个插件,它可以用来定制任何学习路线,并且在你学习的过程中,对你不了解或者有错误i的地方进行改正并加以练习。 你的学习风格、沟通方式、沟通类型、语气和推理框架,Mr. Ranedeer 都能为你做到全方面私人定制。使用的过程中,非氪金玩家尽量使用…