設計模式:觀察者模式 - 實戰

一、觀察者模式場景

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
繁體地址,請注明出處:http://hk.pswp.cn/news/907644.shtml
英文地址,請注明出處:http://en.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;無需親自…