Java设计模式之行为型模式(观察者模式)介绍与说明

一、模式结构

观察者模式包含以下四个角色:

  1. Subject(主题/被观察者)
    • 维护观察者列表,提供注册(registerObserver)、移除(removeObserver)观察者的方法,并定义通知所有观察者的方法(notifyObservers)。
    • 示例:天气数据(WeatherData)、优衣库品牌决策(UniqloBrandDecision)。
  2. Observer(观察者)
    • 定义更新接口(update),用于接收主题的通知并执行响应逻辑。
    • 示例:天气显示组件(CurrentConditionsDisplay)、消费者(Consumer)。
  3. ConcreteSubject(具体主题)
    • 实现主题接口,管理观察者列表,并在状态变化时触发通知。例如,WeatherData类在温度、湿度等数据更新时调用notifyObservers
  4. ConcreteObserver(具体观察者)
    • 实现观察者接口,定义具体响应逻辑。例如,CurrentConditionsDisplay在接收到数据后更新显示内容。

二、核心实现步骤

  1. 定义观察者接口:声明update方法,参数可为数据对象或主题引用(推模型或拉模型)。
  2. 实现具体观察者:在update方法中处理主题状态变化,例如更新UI或执行业务逻辑。
  3. 定义主题接口:包含观察者管理方法和通知方法。
  4. 实现具体主题:维护观察者列表,在状态变化时遍历并调用update方法。

三、代码示例(气象站系统)

// 观察者接口
public interface Observer {void update(float temp, float humidity, float pressure);
}
// 主题接口
public interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}
// 具体主题类(天气数据)
public class WeatherData implements Subject {private List observers = new ArrayList<>();private float temperature, humidity, pressure;@Overridepublic void registerObserver(Observer o) { observers.add(o); }@Overridepublic void removeObserver(Observer o) { observers.remove(o); }@Overridepublic void notifyObservers() {for (Observer o : observers) {o.update(temperature, humidity, pressure);}}public void measurementsChanged() {notifyObservers();}public void setMeasurements(float temp, float humidity, float pressure) {this.temperature = temp;this.humidity = humidity;this.pressure = pressure;measurementsChanged();}
}
// 具体观察者类(当前天气显示)
public class CurrentConditionsDisplay implements Observer {private float temp, humidity;@Overridepublic void update(float temp, float humidity, float pressure) {this.temp = temp;this.humidity = humidity;display();}private void display() {System.out.println("当前温度:" + temp + "℃,湿度:" + humidity + "%");}
}

四、适用场景

  1. 事件驱动系统:如GUI事件处理、按钮点击监听。
  2. 实时数据监控:股票价格变动、传感器数据更新。
  3. 订阅/发布模型:邮件订阅、RSS订阅、消息队列。
  4. 跨模块通知:订单状态变更通知多个服务。

五、优缺点分析

优点缺点
- 解耦主题与观察者,符合开闭原则。- 观察者过多时性能下降。
- 动态扩展观察者,无需修改核心逻辑。- 通知顺序不可控,可能引发依赖链问题。
- 支持广播通信,实现事件驱动机制。- 循环依赖可能导致栈溢出。

六、高级应用与优化

  1. 异步通知:使用线程池处理观察者回调,避免阻塞主题线程。
  2. 事件参数化:通过事件对象(如VoteEvent)传递具体数据,增强灵活性。
  3. 弱引用机制:防止内存泄漏(如使用WeakReference存储观察者)。
  4. 分布式扩展:结合消息队列(如Kafka)实现跨进程观察者。

七、Java内置支持(已过时)

JDK提供java.util.ObservableObserver类,但因设计缺陷(如需手动调用setChanged())已被标记为过时。推荐自定义实现或使用现代框架(如Spring的ApplicationEvent)。


总结

观察者模式通过解耦主题与观察者,实现了灵活的通知机制,广泛应用于事件驱动、实时监控等场景。开发者需权衡性能与扩展性,合理设计通知模型(推/拉)和生命周期管理。

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

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

相关文章

实现一个点击输入框可以弹出的数字软键盘控件 qt 5.12

我们将创建两个自定义组件&#xff1a; 1. NumericInputField&#xff1a;一个输入框&#xff0c;当点击时弹出数字键盘。 2. NumericKeyboard&#xff1a;一个可缩放的数字键盘。 设计思路&#xff1a; - NumericInputField 是一个常规的输入框&#xff0c;但点击后会弹出 Num…

Java 深入解析:JVM对象创建与内存机制全景图

第一章&#xff1a;引言 Java 是一种面向对象的编程语言&#xff0c;对象&#xff08;Object&#xff09;是其最基本的组成单位。Java 的“一切皆对象”不仅体现在语法层面&#xff0c;更体现在运行时&#xff0c;几乎所有数据都以对象形式存在于内存中。 然而&#xff0c;很…

Redis 基本操作笔记

1. Redis 简介 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的键值对存储系统&#xff0c;通常作为数据库、缓存、消息中间件等使用。它支持多种数据类型&#xff0c;包括字符串、哈希、列表、集合、有序集合等。 Redis 特点&#xff1a; 性能&…

Docker从环境配置到应用上云的极简路径

Docker从环境配置到应用上云的极简路径主要包括环境配置、应用容器化、选择云平台及部署应用等步骤&#xff0c;具体如下&#xff1a; - 配置Docker环境&#xff1a; - 安装Docker&#xff1a;根据操作系统下载对应版本的Docker安装包。如在Linux系统中&#xff0c;可使用命令…

Slicer渲染Dicom到nrrd

Slicer渲染Dicom到nrrd 工作中遇到一些处理Dicom数据的需求&#xff0c;个人通过网络上的一些教程 对于原始数据尝试转换到nrrd时&#xff0c;发现部分的窗体数据的渲染方向不一致 进一步发现这些很多定义的方向是跟设备厂家强相关的&#xff0c;不同厂家对于同一段的Dicom参…

QT中设计qss字体样式但是没有用【已解决】

检查一下stylesheet里面是不是有不能被QT读取的CSS语言&#xff0c;可能会跟字体颜色冲突错误示范&#xff1a;/* 错误示例&#xff1a;QSS 中使用 box-shadow */ QPushButton {box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); /* Qt 不支持此属性 */ }删掉就行了如果后续想用阴影…

uniapp获取状态栏高度,胶囊按钮的高度,底部安全区域的高度,自定义导航栏

相关API uni.getSystemInfoSync() uni.getMenuButtonBoundingClientRect() 创建一个utils文件夹&#xff0c;该文件下封装一个systemInfo.js /*** 系统信息工具类* 封装获取系统状态栏、导航栏和安全区域等相关信息的方法*/// 获取系统信息并缓存 const systemInfo uni.get…

jQuery 文本属性值

一、前言在网页开发中&#xff0c;我们经常需要对页面上的文本内容进行操作&#xff0c;例如动态修改段落文字、读取用户输入框的内容、更新按钮文本等。jQuery 提供了简洁而强大的方法来处理这些常见的文本操作需求。本文将带你全面了解 jQuery 中用于操作文本内容的三个核心方…

JAVA并发——为什么Java中的ThreadLocal对key的引用为弱引用

1、ThreadLocal 的用途 给每个线程提供自己独立的变量副本&#xff0c;实现线程间隔离。 常用于&#xff1a; 数据库连接、Session 缓存、用户上下文&#xff08;如 userId&#xff09;线程池中的线程复用时避免共享污染&#xff1b;实现线程封闭的设计模式 2、内存泄漏 使用弱…

【C++】多线程同步三剑客介绍

目录 条件变量 头文件 主要操作函数 1、等待操作 2、唤醒操作 使用示例 信号量 头文件 主要操作函数 1、信号量初始化 2、等待操作&#xff08;P操作&#xff09; 3、信号操作&#xff08;V操作&#xff09; 4、获取信号量值 5、销毁信号量 使用示例 互斥锁 …

《Java Web程序设计》实验报告八 JSP+Servlet+JDBC+MySQL实现课程管理

目 录 一、实验目的 二、实验环境 三、实验步骤和内容 1、小组成员分工&#xff08;共计4人&#xff09; 2、实验方案 3、实验结果与分析 4、项目任务评价 四、遇到的问题和解决方法 五、实验总结 一、实验目的 1、掌握mysql的安装、数据库表单创建 2、掌握JDBC的链接…

基于数据挖掘的课程推荐系统研究

摘要本研究设计并开发了一套基于先进数据挖掘技术的智能化课程推荐系统。该系统创新性地采用了协同过滤算法与内容推荐算法相结合的混合推荐策略&#xff0c;通过深度分析学生在学习平台上的历史行为数据&#xff08;包括选课记录、学习时长、测试成绩等&#xff09;以及课程的…

【SCI 4区推荐】《Journal of Visual Communication and Image Representation》

期刊简介&#xff1a;《视觉传达与图像表示杂志》&#xff08;Journal of Visual Communication and Image Representation&#xff09;致力于发表视觉传达与图像表示领域的最前沿研究&#xff0c;特别强调多学科交叉领域中的新技术和理论应用。这本期刊涵盖的研究范围广泛&…

20250711_Sudo 靶机复盘

target:192.168.43.20 外部打点 &#xff08;文件上传&#xff09; nmap扫一下&#xff0c;80,22 开放 扫目录&#xff0c;发现 README.md [17:04:30] 200 - 664B - /Dockerfile [17:04:38] 200 - 34KB - /LICENSE …

STEP 7-Micro/WIN SMART 编程软件:从入门到精通的使用指南

STEP 7-Micro/WIN SMART 编程软件&#xff1a;从入门到精通的使用指南 在工业自动化控制领域&#xff0c;编程软件是连接工程师与 PLC 的桥梁&#xff0c;而 STEP 7-Micro/WIN SMART 作为 S7-200 SMART PLC 的专用编程工具&#xff0c;以其友好的界面和高效的编程能力备受青睐。…

模型训练与部署注意事项篇---resize

图像大小的影响在 YOLOv 系列模型的训练和推理部署过程中&#xff0c;图像大小的选择是影响模型性能&#xff08;精度、速度、泛化能力&#xff09;的关键因素之一。两者的关系既相互关联&#xff0c;又存在一定的灵活性&#xff0c;具体可从以下几个方面详细分析&#xff1a;一…

【Python】venv:配置独立镜像源

为某个特定的 venv 虚拟环境设置 pip 镜像源&#xff0c;使得该环境下的 pip 安装始终使用自定义镜像源&#xff0c;不影响系统 pip&#xff0c;也不依赖用户级配置文件。环境准备 1. 创建虚拟环境 python -m venv venv2. 激活虚拟环境Windows: .\venv\Scripts\activateLinux/m…

日本语言学校:签证制度类 Prompt 的结构整理路径与策略

日本语言学校&#xff1a;签证制度类 Prompt 的结构整理路径与策略 我们在构建语言留学语义系统的过程中&#xff0c;尝试以“签证风险”为例&#xff0c;探索如何让结构信息被更好地保留下来。本文不介绍 Prompt 本身&#xff0c;也不夸大其作用&#xff0c;而是希望借此与更…

RFCOMM协议详解:串口仿真与TCP/IP协议栈移植技术——面试高频考点与真题解析

一、RFCOMM 协议核心考点与高频面试问题1.1 协议基础与核心功能考点解析&#xff1a;RFCOMM&#xff08;Radio Frequency Communication&#xff09;是蓝牙协议栈中实现串口仿真的核心协议&#xff0c;基于 L2CAP 协议提供类似 RS-232 的可靠数据流传输。其核心功能包括&#x…

【编程实践】利用open3d生成物体的最长边方向并可视化

1 利用3d软件生成一个长方体 边长随意&#xff0c;长度随意 2 导出为模型文件并采样为点云数据 从mesh表面进行采样&#xff0c;点数根据自己需求进行设置&#xff0c;此处设置为100000。采样结果&#xff1a;3 识别OBB外接框并可视化长边方向import numpy as np import open3d…