觀察者 ? 事件總線:一路走來的碎碎念

寫給未來的自己:每次手敲事件模型都要 Google,干脆把思路和踩坑一次性記清楚。文章很長,都是嘮叨,目的是讓自己看兩眼就能把設計理由找回來。


目錄

  1. 為什么我要折騰事件模型?
  2. V0 ─ 單一事件的觀察者模式
  3. V1 ─ 多事件同步總線(類型拆分)
  4. V2 ─ 訂閱者優先級(鏈式調用可控)
  5. V3 ─ 事件優先級 + 異步(削峰 & 隔離)
  6. V4 ─ 組合式單線程總線(順序極致保證)
  7. 經驗小抄

1|為什么我要折騰事件模型?

  • 耦合度:把 if?else 通知邏輯塞在同一個類里,一改就牽一大片,改怕了。
  • 可測試性:希望能單測“發一個事件 → 看誰收到了”,不用啟動整套應用。
  • 面試尬聊:被問到“Spring ApplicationEvent 和 Observer 有啥區別”,含含糊糊很挫。

這篇就是把一次次“為什么要這樣設計”寫進代碼注釋里,別再年年忘。


2|V0 ? 單一事件的觀察者模式

場景:只有一類消息,比如聊天窗口有人發言,監聽者立刻打印出來。
痛點:一旦要支持第二種事件,就得復制粘貼另一套接口。

// ========== MessageEvent ==========
// 最簡單的 POJO,只有一條內容。后面會發現 Event 越寫越胖,這里先別管。
public class MessageEvent {private final String content;public MessageEvent(String content) { this.content = content; }public String content() { return content; }
}// ========== Listener ==========
// 單方法接口,本質就是 Java 版回調。
public interface Listener {void onMessage(MessageEvent e);
}public class ConsolePrinter implements Listener {@Override public void onMessage(MessageEvent e) {// 業務寫死:收到就打印。只演示用。System.out.println("[Printer] " + e.content());}
}// ========== SimplePublisher ==========
// 最小發布者:僅負責遍歷列表,沒有任何順序控制。
public class SimplePublisher {private final List<Listener> listeners = new ArrayList<>();public void addListener(Listener l) { listeners.add(l); }public void publish(String msg) {MessageEvent e = new MessageEvent(msg);// 順序 = addListener 的順序。這里沒做保護性復制,線程安全靠調用方自覺。for (Listener l : listeners) l.onMessage(e);}
}

總結

  • 寫起來爽,讀起來爽,但一旦業務變復雜就原地報廢。
  • 發布者對訂閱者的 具體類型 沒有依賴,但依賴了“只有一種事件”的假設。

3|V1 ? 多事件同步總線

目標:讓 Publisher 不關心 到底是哪種事件,把“事件?訂閱者”關系外提。

3.1 核心接口

/** 所有事件的父類,加時間戳是為了調試時知道誰先誰后。 */

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901961.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901961.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901961.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

windwos腳本 | 基于scrcpy,只投聲音、只投畫面

安裝scrcpy&#xff0c;scrcpy自帶adb 寫腳本命名為 .bat 結尾 注意這里的set "PATHD:\tools\scrcpy-win64-v3.2;%PATH%" 替換成scrcpy的安裝目錄 echo off :: 設置UTF-8編碼 chcp 65001 > nul :: 設置標題 title 手機投屏工具:: 添加 scrcpy 路徑到 PATH set &q…

Android device PCO (protocol configuration options) intro

術語 英文縮寫英文全稱中文PCOprotocol configuration options協議配置選項RILradio interface layer 無線電接口層PCO介紹 PCO(Protocol Configuration Options) 是 3GPP 標準協議(TS 24.008)中定義的核心概念,用于在 LTE/5G 網絡建立 PDN 連接時傳遞動態配置參數(如 D…

Spring Boot配置文件優先級全解析:如何優雅覆蓋默認配置?

&#x1f4da; 一、為什么需要了解配置文件優先級&#xff1f; 想象一下&#xff0c;你正在玩一個游戲&#x1f3ae;&#xff0c;游戲里有默認設置&#xff0c;但你可以通過不同的方式修改這些設置&#xff1a; 游戲內置的默認設置&#xff08;就像Spring Boot的默認配置&…

汽車行駛工況特征參數:從“速度曲線”到“駕駛DNA”的硬核解碼

作為新能源汽車行業的從業者&#xff0c;你是否曾困惑于這些問題&#xff1a; 為什么同一款電動車&#xff0c;不同用戶的實際續航差異高達30%&#xff1f;如何精準量化駕駛行為對電池壽命的影響&#xff1f;車企標定的“NEDC續航”與真實路況差距的根源是什么&#xff1f; 這…

HTTP 2.0 協議特性詳解

1. 使用二進制協議&#xff0c;簡化傳輸的復雜性&#xff0c;提高了效率 2. 支持一個 TCP 鏈接發起多請求&#xff0c;移除 pipeline HTTP/2 移除了 HTTP/1.1中的管道化&#xff08;pipeline&#xff09;機制&#xff0c;轉而采用多路復用&#xff08;Multiplexing&#xff0…

完美解決瀏覽器不能復制的問題(比如賽氪網的中題庫練習題)

僅供復制題庫題目進行打印學習使用&#xff01; 最近想把賽氪網題庫中的題目打印出來做練習&#xff0c;發現題庫中的題目不能復制&#xff0c;不能在試卷上勾畫標記太難受了&#xff0c;而且不能留作材料以后復習&#xff0c;故出此策。 而且CtrlP打印出的pdf會缺少題目。(我…

std::set (C++)

std::set 1. 概述定義特點 2. 內部實現3. 性能特征4. 常用 API5. 使用示例6. 自定義比較器7. 注意事項與優化8. 使用建議 1. 概述 定義 template<class Key,class Compare std::less<Key>,class Allocator std::allocator<Key> > class std::set;特點 有…

SSM省市區三級聯動和三表聯查附帶數據庫

SSM省市區三級聯動和三表聯查 ------附帶數據庫碼云地址&#xff1a;https://gitee.com/Mr_ZKC/NO1 數據庫在項目中

曲棍球·棒球1號位

中國女子曲棍球隊曾涌現過馬弋博、李紅俠等優秀選手&#xff0c;但“李紅”這一名字可能為信息誤差。以下為您系統介紹曲棍球&#xff0c;并結合棒球進行對比分析&#xff1a; 曲棍球&#xff08;Hockey&#xff09;核心特點 運動形式 分為草地曲棍球&#xff08;夏季奧運會項…

12芯束裝光纖不同包層線顏色之間的排列順序

為什么光纖線必須按照以下顏色順序進行排序&#xff1f;這其實是為了防止光污染的問題&#xff0c;不同顏色在傳遞光時從包層表皮漏光傳感到梳妝的其它纖芯上&#xff0c;會有光污染的問題&#xff0c;而為了減少并防止光污染的現象&#xff0c;所以在光通信之中&#xff0c;需…

c++程序的打包編譯cmake+make

c打包編譯 1 在不用系統中打包介紹1.1 linux中打包c程序的2種方式1.2 windows中打包c程序1.3 cmakeNinja和cmakemake的兩種方式對比1.3.1 Ninja是什么&#xff08;可以認為是make工具的一個替代產品&#xff09;1.3.2 cmakeNinja可以用于linux和windows系統中&#xff0c;編譯效…

Spark on K8s 在 vivo 大數據平臺的混部實戰與優化

一、Spark on K8s 簡介 (一)定義與架構 Spark on K8s 是一種將 Spark 運行在 Kubernetes(K8s)集群上的架構,由 K8s 直接創建 Driver 和 Executor 的 Pod 來運行 Spark 作業。其架構如下。 Driver Pod:相當于 Spark 集群中的 Driver,負責作業的調度和管理,它會根據作業…

MDA測量數據查看器【內含工具和源碼地址】

一、工具介紹 MDA測量數據查看器用于顯示和分析以MDF格式提供的測量數據。 支持MDF3.3之前含MDF3.3的二進制格式&#xff0c;支持Vector CANape and ETAS Inca. Kvaser CAN Logger (MDF 3.2) 文件。 MDF (Measurement Data Format)是一種二進制文件&#xff0c;用來記錄、交換…

番外篇 | SEAM-YOLO:引入SEAM系列注意力機制,提升遮擋小目標的檢測性能

前言:Hello大家好,我是小哥談。SEAM(Squeeze-and-Excitation Attention Module)系列注意力機制是一種高效的特征增強方法,特別適合處理遮擋和小目標檢測問題。該機制通過建模通道間關系來自適應地重新校準通道特征響應。在遮擋小目標檢測中的應用優勢包括:1)通道注意力增強…

使用VHDL語言實現TXT文件的讀寫操作

使用FPGA進行圖像處理時&#xff0c;通常需要將TXT文件中的圖像數據讀出到TestBench中&#xff0c;并將仿真的結果寫入到TXT文件中&#xff0c;用于確認圖像處理的結果是否正確。 VHDL中TXT文件的讀寫操作如下所示&#xff0c; --------------------------------------------…

基于Redis的4種延時隊列實現方式

延時隊列是一種特殊的消息隊列&#xff0c;它允許消息在指定的時間后被消費。在微服務架構、電商系統和任務調度場景中&#xff0c;延時隊列扮演著關鍵角色。例如&#xff0c;訂單超時自動取消、定時提醒、延時支付等都依賴延時隊列實現。 Redis作為高性能的內存數據庫&#x…

GN ninja 工程化構建例程

文章目錄 1. 前言?2. 工程實例??2.1 工程目錄結構2.2 工程頂層.gn文件2.3 工具鏈配置.gn文件2.4 編譯配置.gn文件2.5 編譯目標配置.gn文件2.6 工程接口文件2.7 動態庫編譯.gn文件2.8 動態庫源文件2.9 靜態庫編譯.gn文件2.10 靜態庫源文件2.11 主程序編譯.gn文件2.12 主程序源…

基于亞博K210開發板——內存卡讀寫文件

開發板 亞博K210開發板 實驗目的 本實驗主要學習 K210 通過 SPI 讀寫內存卡文件的功能 實驗準備 實驗元件 開發板自帶的 TF 卡、LCD 顯示屏 &#xff08;提前準備好 FAT32 格式的TF 卡。TF 插入 TF 卡槽的時候注意方向&#xff0c;TF 卡的金手指那一面需要面向開發板&am…

51單片機實驗五:A/D和D/A轉換

一、實驗環境與實驗器材 環境&#xff1a;Keli&#xff0c;STC-ISP燒寫軟件,Proteus. 器材&#xff1a;TX-1C單片機&#xff08;STC89C52RC&#xff09;、電腦。 二、 實驗內容及實驗步驟 1.A/D轉換 概念&#xff1a;模數轉換是將連續的模擬信號轉換為離散的數字信…