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

核心概念

观察者模式包含以下核心角色:

  1. Subject(主题/被观察者)

    • 维护观察者列表
    • 提供注册、删除和通知观察者的接口
  2. ConcreteSubject(具体主题)

    • 实现Subject接口
    • 管理自身状态,并在状态变化时通知所有观察者
  3. Observer(观察者)

    • 定义更新接口,接收主题通知
  4. ConcreteObserver(具体观察者)

    • 实现Observer接口
    • 根据主题的状态变化执行具体操作

模式特点

  • 松耦合‌:主题和观察者之间松耦合
  • 自动通知‌:状态变化时自动通知观察者
  • 一对多‌:一个主题可对应多个观察者
  • 动态订阅‌:可动态添加/删除观察者

应用场景

观察者模式适用于以下场景:

  1. 消息发布/订阅系统‌:如聊天室、新闻推送
  2. 用户界面组件‌:GUI事件处理
  3. 实时数据监控‌:如股票价格变动、温度监控
  4. 事件驱动系统‌:如游戏引擎、企业监控系统
  5. 分布式系统‌:节点状态变更通知

代码实现示例

以下是观察者模式的基本实现(推模型):

// 观察者接口
public interface Observer {void update(String message);
}// 主题接口
public interface Subject {void registerObserver(Observer o);void removeObserver(Observer o);void notifyObservers();
}// 具体主题 - 新闻发布中心
public class NewsAgency implements Subject {private List<Observer> observers = new ArrayList<>();private String news;public void setNews(String news) {this.news = news;notifyObservers();}public void registerObserver(Observer o) {observers.add(o);}public void removeObserver(Observer o) {observers.remove(o);}public void notifyObservers() {for (Observer o : observers) {o.update(news);}}
}// 具体观察者 - 新闻订阅者
public class NewsSubscriber implements Observer {private String name;public NewsSubscriber(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + " 收到新闻: " + message);}
}

通知模型对比

观察者模式有两种主要的通知模型:

模型类型数据传递方式优点缺点
推模型主题主动推送详细数据给观察者实时性强,响应快可能传递冗余数据
拉模型观察者收到通知后主动拉取数据按需获取,灵活性高增加主题的访问压力

Java内置支持

Java在java.util包中提供了观察者模式的实现:

  • Observable类(主题)
  • Observer接口

但自Java 9起已被标记为@Deprecated,推荐使用java.beans包中的PropertyChangeListenerPropertyChangeSupport

优缺点分析

优点‌:

  1. 主题和观察者之间松耦合
  2. 支持广播通信
  3. 符合开放-封闭原则
  4. 可动态添加/删除观察者

缺点‌:

  1. 通知顺序不可控
  2. 观察者过多时可能影响性能
  3. 可能导致循环依赖
  4. 观察者不知道彼此存在,可能导致更新冲突

实际应用案例

  1. 聊天系统‌:聊天室作为主题,用户作为观察者
  2. 温度监控系统‌:温度传感器作为主题,显示设备和报警系统作为观察者
  3. 彩票系统‌:彩票中心作为主题,购彩者作为观察者
  4. 企业监控系统‌:员工电脑作为主题,安全模块作为观察者

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

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

相关文章

创世新布控球 国标

目录 结论&#xff1a; UDP模式 对讲 平台页面设置 设备tcp被动 旧的创世版本&#xff08;平台选的设备tcp被动&#xff1b;设备侧无法设置&#xff09; 新创世从2.8改到180上&#xff0c;先UDP&#xff0c;全报文 参考文档 结论&#xff1a; 对讲的tcp主被动&#xff0…

【Dify精讲】第18章:企业级功能定制

在企业级AI应用的实际部署中&#xff0c;你很快就会发现开源版本的标准功能往往无法满足复杂的业务需求。作为一个在多家企业实施AI系统的老兵&#xff0c;我深知企业级定制的痛点和需求。今天&#xff0c;让我们一起深入Dify的企业级功能定制&#xff0c;看看如何在现有架构基…

PHP $_GET 变量详解

PHP $_GET 变量详解 引言 在PHP编程中,$_GET变量是处理HTTP GET请求参数的一种非常便捷的方式。本文将详细介绍PHP $_GET变量的使用方法、特点以及在实际开发中的应用。 一、什么是$_GET变量? $_GET是一个预定义的PHP超级全局变量,用于存储HTTP GET请求中的数据。当用户…

Kafka动态配置深度解析

在分布式消息队列领域&#xff0c;Kafka凭借其高吞吐量、低延迟和可扩展性成为众多企业的首选。随着业务场景的日益复杂和数据流量的动态变化&#xff0c;静态配置已难以满足需求&#xff0c;Kafka的动态配置功能应运而生。通过动态配置&#xff0c;用户无需重启集群或中断服务…

为WIN10微软输入法的全角切换Bug禁用Shift+Space组合键

20250621 By wdhuag 目录 前言&#xff1a; 参考&#xff1a; 使用AutoHotkey屏蔽快捷键&#xff08;推荐&#xff09;&#xff1a; 使用PowerToys的键盘管理器屏蔽快捷键&#xff08;不推荐&#xff09;&#xff1a; 网上其它的方法&#xff1a; 前言&#xff1a; 是的…

Shell脚本调试与错误处理详解

在 Shell 脚本中&#xff0c;set 命令用于控制脚本的执行行为和调试选项。以下是详细解释&#xff1a; 1. set -e 和 set e set -e&#xff08;严格错误检查&#xff09;&#xff1a; 当命令返回非零退出状态&#xff08;失败&#xff09;时&#xff0c;立即退出脚本。 示例&a…

鲲鹏服务器创建Zookeeper镜像实例

配置Kafka过程中&#xff0c;少不了要使用Zookeeer&#xff0c;这里记录一下配置Zookeeper镜像实例的过程。 创建目录 mkdir -p /data/docker/zookeeper/data mkdir -p /data/docker/zookeeper/conf mkdir -p /data/docker/zookeeper/logs说明&#xff1a;data目录为数据挂载…

GitHub Actions 自动 CI 测试 WorkFlow工作流搭建

大家好&#xff0c;我是此林。 代码托管平台 Github 我们应该比较熟悉。每次我们提交代码到 GitHub 仓库时&#xff0c;特别是开源项目&#xff0c;一般都会自动触发测试脚本运行&#xff0c;帮你验证代码没有引入新的错误。 这个其实就是 GitHub Actions&#xff0c;一般我们…

0-机器学习简介

有监督学习 目标&#xff1a;建立一个模型(函数)&#xff0c;来描述输入(x)和输出(y)之间的映射关系。 价值&#xff1a;模型训练完成后&#xff0c;新的输入&#xff0c;模型会给出预测值输出。 注意点&#xff1a; 1.要有足够的训练样本 2.输入和输出之间有关联关系 3.输入…

前端跨域解决方案(6):Nginx

1 Nginx 核心 Nginx 是一个开源的高性能 HTTP 和反向代理服务器&#xff0c;以轻量级、高并发处理能力和低资源消耗著称。除作为 Web 服务器外&#xff0c;还可充当邮件代理服务器和通用的 TCP/UDP 代理服务器&#xff0c;广泛应用于现代 Web 架构中。 在 Windows 系统中使用…

C++智能指针编程实例

智能指针是C11引入的重要特性&#xff0c;用于自动管理动态分配的内存&#xff0c;防止内存泄漏。下面介绍几种高级智能指针编程实例。 1. 共享所有权模式 (shared_ptr) 循环引用问题及解决方案 #include <memory> #include <iostream>class B; // 前向声明clas…

单元测试总结

一、测试方案: 单元测试方案应包括以下步骤: 1.理解代码结构:仔细阅读代码,理解程序的结构、逻辑和算法。 2.制定测试目标:明确你想要测试的功能和输出结果; 3.撰写测试用例:编写涵盖所有测试目标的测试用例; 4.执行测试:运行测试用例以验证功能的正确性; 5.编写报告:根据测试…

Spring面向切面编程AOP(2)

前置通知&#xff08;Before Advice&#xff09; 前置通知在目标方法执行之前被调用&#xff0c;常用于执行一些预处理逻辑&#xff0c;例如权限验证、参数校验等。在 Spring 配置文件中&#xff0c;前置通知通过<aop:before>标签进行配置&#xff0c;以下是一个典型的示…

设备故障预测与健康管理技术:从数据到决策的工业智能进化之路​

在工业 4.0 与智能制造浪潮的推动下&#xff0c;设备故障预测与健康管理&#xff08;Prognostics and Health Management, PHM&#xff09;技术已成为企业实现数字化转型的核心驱动力。据统计&#xff0c;制造业中设备非计划停机 1 小时的平均损失高达 25 万美元&#xff0c;而…

RabbitMQ从入门到实践:消息队列核心原理与典型应用场景

在现代应用开发中&#xff0c;系统各部分之间的通信至关重要。这就是像RabbitMQ这样的消息代理发挥作用的地方。无论您是在构建微服务架构、实现任务队列&#xff0c;还是开发实时聊天应用程序&#xff0c;RabbitMQ都可能成为改变游戏规则的工具。本文将深入探讨RabbitMQ是什么…

基于Spring Boot和Vue的网上军事论坛设计与实现

目录 一.&#x1f981;前言二.&#x1f981;开源代码与组件使用情况说明三.&#x1f981;核心功能1. ✅算法设计2. ✅Java开发语言3. ✅Redis数据库4. ✅部署项目 四.&#x1f981;演示效果1. 管理员模块1.1 用户管理1.2 内容审核1.3 权限分配1.4 菜单管理1.5 字典管理 2. 用户…

LLMs基础学习(八)强化学习专题(6)

LLMs基础学习&#xff08;八&#xff09;强化学习专题&#xff08;6&#xff09; 文章目录 LLMs基础学习&#xff08;八&#xff09;强化学习专题&#xff08;6&#xff09;深度强化学习&#xff08;DQN&#xff09;DQN 起源&#xff1a;《Playing Atari with Deep Reinforceme…

JVM(10)——详解Parallel垃圾回收器

Parallel 垃圾回收器&#xff08;也称为 吞吐量优先收集器&#xff09;。它是 Java 早期&#xff08;特别是 JDK 8 及之前&#xff09;在多核处理器上的默认垃圾回收器&#xff0c;其核心设计目标是最大化应用程序的吞吐量。 一、Parallel 回收器的定位与设计目标 核心目标&am…

MySQL(91)什么是分布式数据库?

分布式数据库是一种将数据存储在多个物理位置的数据库系统。这些位置可能分布在不同的服务器、数据中心甚至地理位置。分布式数据库系统允许数据的存储、处理和访问分布在多个节点上&#xff0c;以提高数据的可用性、可靠性、可扩展性和性能。 1. 分布式数据库的特点 1.1 数据…

Java事务失效(面试题)的常见场景

1. 方法非public修饰 原理&#xff1a; Spring AOP代理&#xff08;CGLIB或JDK动态代理&#xff09;默认无法拦截非public方法。 示例&#xff1a; Service public class UserService {Transactionalvoid updateUser() { // 非public方法// 事务不会生效&#xff01;} } 修…