设计模式:观察者模式 - 实战

一、观察者模式场景

1.1 什么是观察者模式?
观察者模式(Observer Pattern)观察者模式是一种行为型设计模式,用于定义一种一对多的依赖关系,当对象的状态发生变化时,所有依赖于它的对象都会自动收到通知并更新。

核心思想观察者模式实现了对象之间的解耦:被观察者(Subject)专注于自身状态的管理,而观察者(Observer)专注于对状态变化的响应,二者通过通知机制进行交互

1.2 传统开发模式的三大死穴

强耦合陷阱:订单状态变更需要手动调用10+通知服务(邮件/SMS/物流…)

扩展噩梦:新增通知渠道必须修改核心业务代码(违反OCP原则)

性能瓶颈:同步调用链导致接口响应时间突破2秒红线

1.3 观察者模式的破局之道
事件驱动架构:业务逻辑与事件处理物理隔离

动态扩展能力:新增观察者零侵入核心系统

异步削峰:实测QPS提升300%(订单支付场景)

1.4 优点

解耦:被观察者和观察者之间的耦合度低,便于扩展。

动态联动:可以动态添加、移除观察者,灵活性强。

符合开闭原则:被观察者的状态变化通知机制对扩展开放,对修改关闭。

1.5 缺点

性能问题:观察者过多时,通知机制可能导致性能开销。

复杂性增加:过多的观察者与被观察者关系可能增加系统的复杂性。

可能产生循环依赖:若观察者与被观察者相互依赖,可能导致循环调用。

1.6 应用场景

事件驱动模型:如 UI 事件监听器(按钮点击等)。

发布-订阅机制:消息队列、事件总线等。

状态同步:某一对象的状态变化需要通知多个依赖对象时。

二、技术方案设计

2.1 架构演进对比
在这里插入图片描述

2.2 核心组件设计

[事件源] --发布--> [EventBus] --通知--> [观察者集群]↑                    ↖[事件对象]               [线程池分发]

三、Java原生实现

3.1 基于JDK的经典实现

// 支付成功事件定义
public class PaymentSuccessEvent extends EventObject {private final String orderId;private final BigDecimal amount;public PaymentSuccessEvent(Object source, String orderId, BigDecimal amount) {super(source);this.orderId = orderId;this.amount = amount;}
}// 支付服务(事件源)
public class PaymentService {private final List<EventListener> listeners = new CopyOnWriteArrayList<>();public void addListener(EventListener listener) {listeners.add(listener);}public void pay(String orderId, BigDecimal amount) {// 支付核心逻辑...notifyListeners(new PaymentSuccessEvent(this, orderId, amount));}private void notifyListeners(PaymentSuccessEvent event) {listeners.forEach(listener -> listener.onEvent(event));}
}// 邮件通知观察者
public class EmailNotifier implements EventListener {@Overridepublic void onEvent(EventObject event) {if (event instanceof PaymentSuccessEvent) {PaymentSuccessEvent e = (PaymentSuccessEvent) event;sendEmail(e.getOrderId(), e.getAmount());}}
}

3.2 Java9+改进方案

// 使用Flow API实现响应式流
public class PaymentPublisher implements Flow.Publisher<PaymentEvent> {private final Executor executor = ForkJoinPool.commonPool();private final List<Flow.Subscriber<? super PaymentEvent>> subscribers = new CopyOnWriteArrayList<>();@Overridepublic void subscribe(Flow.Subscriber<? super PaymentEvent> subscriber) {subscribers.add(subscriber);subscriber.onSubscribe(new PaymentSubscription(subscriber));}private class PaymentSubscription implements Flow.Subscription {private final Flow.Subscriber<? super PaymentEvent> subscriber;PaymentSubscription(Flow.Subscriber<? super PaymentEvent> subscriber) {this.subscriber = subscriber;}@Overridepublic void request(long n) {// 背压处理}@Overridepublic void cancel() {subscribers.remove(subscriber);}}
}

四、Spring生态进阶实现

4.1 基于ApplicationEvent

// 配置中心变更事件
public class ConfigUpdateEvent extends ApplicationEvent {private final String configKey;private final String newValue;public ConfigUpdateEvent(Object source, String configKey, String newValue) {super(source);this.configKey = configKey;this.newValue = newValue;}
}// 动态配置观察者
@Component
public class ConfigRefreshListener {@EventListener@Asyncpublic void handleConfigUpdate(ConfigUpdateEvent event) {refreshConfigCache(event.getConfigKey(), event.getNewValue());notifyAllServers(event);}
}// 事件发布
@Service
public class ConfigService {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void updateConfig(String key, String value) {// 更新数据库eventPublisher.publishEvent(new ConfigUpdateEvent(this, key, value));}
}

4.2 注解驱动增强

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BusinessEventListener {String[] keys() default {};EventMode mode() default EventMode.ASYNC;
}// AOP切面处理
@Aspect
@Component
public class EventListenerAspect {@Around("@annotation(listener)")public Object processEvent(ProceedingJoinPoint pjp, BusinessEventListener listener) {EventObject event = (EventObject) pjp.getArgs()[0];if (shouldHandle(event, listener.keys())) {return switch (listener.mode()) {case ASYNC -> CompletableFuture.runAsync(() -> proceed(pjp));case TRANSACTIONAL -> executeInTransaction(pjp);default -> proceed(pjp);};}return null;}
}

五、生产级优化方案

5.1 性能优化策略
在这里插入图片描述

5.2 可靠性保障

// 事件持久化方案
public class PersistentEventBus {private final EventStoreRepository eventStore;@Transactional(propagation = Propagation.REQUIRES_NEW)public void publishWithPersistence(DomainEvent event) {eventStore.save(event);realPublish(event);}// 定时补偿任务@Scheduled(fixedRate = 60000)public void retryFailedEvents() {eventStore.findFailedEvents().forEach(event -> {try {realPublish(event);event.markAsSent();} catch (Exception e) {event.recordRetry();}});}
}

六、经典应用场景

6.1 电商订单系统

支付成功事件 → 库存扣减/物流触发/积分发放使用「发布-确认-补偿」机制保证最终一致性

6.2 微服务配置中心

配置变更事件 → 所有服务实例动态刷新结合Spring Cloud Bus实现集群通知

6.3 物联网数据采集

设备状态事件 → 实时监控/预警分析/大屏展示采用MQTT协议实现百万级设备连接

七、避坑指南

7.1 常见问题排查
内存泄漏:

检查观察者是否及时取消注册

使用WeakReference包装监听器

事件丢失:

增加本地事件持久化层

实现至少一次投递语义

循环触发:

在事件对象中添加traceId

设置最大传播深度阈值

7.2 生产注意事项
事件版本控制:使用Avro Schema管理事件格式

监控埋点:统计事件处理耗时/成功率

熔断降级:Hystrix隔离异常观察者

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

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

相关文章

Axure中继器交互完全指南:核心函数解析×场景实战×避坑策略(懂得才能应用)

亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!如有帮助请订阅专栏! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 主要内容:中继器核心函数解析、场景方法详解、注意事项、特殊函数区别 课程目标:提高中继器的掌握…

【设计模式-4.5】行为型——迭代器模式

说明&#xff1a;本文介绍设计模式中&#xff0c;行为型设计模式之一的迭代器模式。 定义 迭代器模式&#xff08;Iterator Pattern&#xff09;&#xff0c;也叫作游标模式&#xff08;Cursor Pattern&#xff09;&#xff0c;它提供一种按顺序访问集合/容器对象元素的方法&…

鸿蒙OSUniApp自定义手势识别与操作控制实践#三方框架 #Uniapp

UniApp自定义手势识别与操作控制实践 引言 在移动应用开发中&#xff0c;手势交互已经成为提升用户体验的重要组成部分。本文将深入探讨如何在UniApp框架中实现自定义手势识别与操作控制&#xff0c;通过实际案例帮助开发者掌握这一关键技术。我们将以一个图片查看器为例&…

【数据结构】树形结构--二叉树

【数据结构】树形结构--二叉树 一.知识补充1.什么是树2.树的常见概念 二.二叉树&#xff08;Binary Tree&#xff09;1.二叉树的定义2.二叉树的分类3.二叉树的性质 三.二叉树的实现1.二叉树的存储2.二叉树的遍历①.先序遍历②.中序遍历③.后序遍历④.层序遍历 一.知识补充 1.什…

从认识AI开始-----解密LSTM:RNN的进化之路

前言 我在上一篇文章中介绍了 RNN&#xff0c;它是一个隐变量模型&#xff0c;主要通过隐藏状态连接时间序列&#xff0c;实现了序列信息的记忆与建模。然而&#xff0c;RNN在实践中面临严重的“梯度消失”与“长期依赖建模困难”问题&#xff1a; 难以捕捉相隔很远的时间步之…

接地气的方式认识JVM(一)

最近在学jvm&#xff0c;浮于表面的学了之后&#xff0c;发现jvm并没有我想象中的那么神秘&#xff0c;这篇文章将会用接地气的方式来说一说这些jvm的相关概念以及名词解释。 带着下面两个问题来阅读 认识了解JVM大致有什么在代码运行时的都在背后做了什么 JVM是个啥&#xf…

Next.js 15 与 Apollo Client 的现代集成及性能优化

Next.js 15 与 Apollo Client 的现代集成及性能优化 目录 技术演进集成实践性能优化应用案例未来趋势 技术演进 Next.js 15 核心特性对开发模式的革新 Next.js 15 通过引入 App Router、服务器组件&#xff08;Server Components&#xff09;和客户端组件&#xff08;Clie…

无人机桥梁3D建模、巡检、检测的航线规划

无人机桥梁3D建模、巡检、检测的航线规划 无人机在3D建模、巡检和检测任务中的航线规划存在显著差异&#xff0c;主要体现在飞行高度、航线模式、精度要求和传感器配置等方面。以下是三者的详细对比分析&#xff1a; 1. 核心目标差异 任务类型主要目标典型应用场景3D建模 生成…

Hive数据倾斜问题深度解析与实战优化指南

一、数据倾斜现象的本质与危害 数据倾斜是Hive在MapReduce计算过程中,​部分Key对应的数据量远超其他Key,导致少数Reducer任务处理时间远高于其他任务的性能瓶颈问题。典型表现为: ​作业进度卡在99%​​:99%的Reducer已完成,剩余1%持续数小时​资源利用率失衡​:部分节…

VRRP 原理与配置:让你的网络永不掉线!

VRRP 原理与配置&#xff1a;让你的网络永不掉线&#xff01; 一. VRRP 是什么&#xff0c;为什么需要它&#xff1f;二. VRRP 的核心概念三. VRRP 的工作原理四. 华为设备 VRRP 配置步骤 &#xff08;主备模式&#xff09;4.1 拓扑示例4.2 &#x1f6e0; 配置步骤 五. VRRP 配…

解决开发者技能差距:AI 在提升效率与技能培养中的作用

企业在开发者人才方面正面临双重挑战。一方面&#xff0c;IDC 预测&#xff0c;到2025年&#xff0c;全球全职开发者将短缺400万人&#xff1b;另一方面&#xff0c;一些行业巨头已暂停开发者招聘&#xff0c;转而倚重人工智能&#xff08;AI&#xff09;来满足开发需求。这不禁…

痛点即爆点?如何挖掘客户的痛点和需求?

销售的核心在于精准洞察客户需求与痛点&#xff0c;并运用专业能力为其提供定制化解决方案&#xff0c;从而消除客户顾虑、解决问题&#xff0c;最终实现双赢。而快速识别客户痛点&#xff0c;不仅是成交的关键&#xff0c;更是建立专业形象、赢得客户信任的核心能力。那么&…

云服务器如何自动更新系统并保持安全?

云服务器自动更新系统是保障安全、修补漏洞的重要措施。下面是常见 Linux 系统&#xff08;如 Ubuntu、Debian、CentOS&#xff09;和 Windows 服务器自动更新的做法和建议&#xff1a; 1. Linux 云服务器自动更新及安全维护 Ubuntu / Debian 系统 手动更新命令 sudo apt up…

fvm install 下载超时 过慢 fvm常用命令、flutter常用命令

Git 配置问题 确保 Git 使用的是 HTTPS&#xff0c;而不是 SSH。如果你有 .gitconfig&#xff0c;确保没有配置奇怪的代理&#xff1a; git config --global --get http.proxy git config --global --get https.proxy如果有代理设置且不需要&#xff0c;取消代理&#xff1a;…

多语种OCR识别系统,引领文字识别新时代

在全球化与数字化深度融合的今天&#xff0c;语言障碍成为企业跨国协作、信息管理的一大挑战。无论是跨国合同签署、多语言档案管理&#xff0c;还是跨境商务沟通&#xff0c;高效精准的文字识别技术已成为刚需。中安智能OCR多语种识别系统应运而生&#xff0c;凭借其强大的光学…

Pyenv 使用指南:多版本 Python 环境管理

目录 Pyenv 是什么&#xff1f;安装 Pyenv管理 Python 版本虚拟环境管理项目级 Python 版本控制高级技巧常见问题解决最佳实践 Pyenv 是什么&#xff1f; Pyenv 是一个强大的 Python 版本管理工具&#xff0c;允许你&#xff1a; 在同一台机器上安装多个 Python 版本轻松切换…

Windows 11 家庭版 安装Docker教程

Windows 家庭版需要通过脚本手动安装 Hyper-V 一、前置检查 1、查看系统 快捷键【winR】&#xff0c;输入“control” 【控制面板】—>【系统和安全】—>【系统】 2、确认虚拟化 【任务管理器】—【性能】 二、安装Hyper-V 1、创建并运行安装脚本 在桌面新建一个 .…

leetcode:479. 最大回文数乘积(python3解法,数学相关算法题)

难度&#xff1a;简单 给定一个整数 n &#xff0c;返回 可表示为两个 n 位整数乘积的 最大回文整数 。因为答案可能非常大&#xff0c;所以返回它对 1337 取余 。 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;987 解释&#xff1a;99 x 91 9009, 9009 % 1337 …

VR看房系统,新生代看房新体验

VR看房系统的概念 虚拟现实&#xff08;VirtualReality,VR&#xff09;看房系统&#xff0c;是近年来随着科技进步在房地产行业中兴起的一种创新看房方式。看房系统利用先进的计算机技术模拟出一个三维环境&#xff0c;使用户能够身临其境地浏览和体验房源&#xff0c;无需亲自…