Java設計模式之中介者模式詳解

Java設計模式之中介者模式詳解


一、中介者模式核心思想

核心目標通過中介對象封裝一組對象間的交互,將網狀的對象關系轉變為星型結構。如同機場控制塔協調所有飛機的起降,避免飛機之間直接通信導致的混亂。


二、中介者模式類圖(Mermaid)

協調
協調
通信
?interface?
Mediator
+notify(Component, String)
ConcreteMediator
-componentA: ComponentA
-componentB: ComponentB
+notify(Component, String)
?abstract?
Component
-mediator: Mediator
+setMediator(Mediator)
+notifyMediator(String)
ComponentA
+operationA()
+reactToB()
ComponentB
+operationB()
+reactToA()

三、代碼實現示例

1. 聊天室場景

// 中介者接口
interface ChatMediator {void sendMessage(String msg, User user);void addUser(User user);
}// 具體中介者:聊天室
class ChatRoom implements ChatMediator {private List<User> users = new ArrayList<>();public void addUser(User user) {users.add(user);}public void sendMessage(String msg, User sender) {for (User user : users) {if (user != sender) {  // 不發送給自己user.receive(msg);}}}
}// 抽象組件
abstract class User {protected ChatMediator mediator;protected String name;public User(String name, ChatMediator mediator) {this.name = name;this.mediator = mediator;}public abstract void send(String msg);public abstract void receive(String msg);
}// 具體組件:聊天用戶
class ChatUser extends User {public ChatUser(String name, ChatMediator mediator) {super(name, mediator);}public void send(String msg) {System.out.println(name + " 發送: " + msg);mediator.sendMessage(msg, this);}public void receive(String msg) {System.out.println(name + " 收到: " + msg);}
}// 客戶端調用
public class Client {public static void main(String[] args) {ChatMediator chatRoom = new ChatRoom();User alice = new ChatUser("Alice", chatRoom);User bob = new ChatUser("Bob", chatRoom);User charlie = new ChatUser("Charlie", chatRoom);chatRoom.addUser(alice);chatRoom.addUser(bob);chatRoom.addUser(charlie);alice.send("大家好!");/* 輸出:Alice 發送: 大家好!Bob 收到: 大家好!Charlie 收到: 大家好! */}
}

四、模式優缺點分析

? 優勢

  • 解耦對象關系:組件間無需直接引用
  • 簡化交互協議:統一通過中介者通信
  • 集中控制邏輯:交互規則在中介者中維護
  • 減少子類數量:避免為不同交互創建大量子類

? 缺點

  • 中介者可能復雜:隨著交互增加,中介者可能成為"上帝對象"
  • 性能瓶頸:所有通信經過中介者,可能成為系統瓶頸
  • 過度設計風險:簡單交互場景不適用

五、典型應用場景

  1. GUI組件交互:表單驗證(輸入框、按鈕、標簽聯動)
  2. 聊天系統:群聊消息分發
  3. 航空管制:協調飛機起降
  4. 分布式系統:服務注冊與發現(如Eureka)
  5. 工作流引擎:任務節點間的協調
  6. 游戲開發:NPC行為協調

六、Mermaid序列圖(交互流程)

ComponentA Mediator ComponentB ComponentC 通知事件X 處理事件X 處理事件X 完成 完成 反饋結果 ComponentA Mediator ComponentB ComponentC

七、中介者模式 vs 其他模式

對比模式核心區別
觀察者模式單向通知,不處理響應
外觀模式簡化子系統接口,不處理組件間交互
代理模式控制單個對象訪問

八、實際框架應用案例

1. Java Message Service (JMS)

classDiagramclass ConnectionFactoryclass Connectionclass Sessionclass MessageProducerclass MessageConsumerConnectionFactory --> Connection : 創建Connection --> Session : 創建Session --> MessageProducer : 創建Session --> MessageConsumer : 創建MessageProducer --> Message : 發送MessageConsumer --> Message : 接收note for ConnectionFactory "作為中介者協調\n生產者與消費者"

2. Spring框架中的ApplicationContext

@Component
class ServiceA {@Autowired private ApplicationContext context;  // 中介者public void doSomething() {// 通過中介者獲取其他組件ServiceB serviceB = context.getBean(ServiceB.class);serviceB.process();}
}

九、高級應用技巧

1. 中介者分層設計

協調
協調
GlobalMediator
ModuleAMediator
ModuleBMediator
ComponentA1
ComponentA2

2. 事件總線(簡化版)

class EventBusMediator {private Map<Class<?>, List<Consumer<Object>>> handlers = new HashMap<>();public <T> void subscribe(Class<T> eventType, Consumer<T> handler) {handlers.computeIfAbsent(eventType, k -> new ArrayList<>()).add((Consumer<Object>) handler);}public void publish(Object event) {List<Consumer<Object>> eventHandlers = handlers.get(event.getClass());if (eventHandlers != null) {eventHandlers.forEach(handler -> handler.accept(event));}}
}// 使用示例
EventBusMediator bus = new EventBusMediator();
bus.subscribe(String.class, msg -> System.out.println("處理字符串: " + msg));
bus.publish("測試消息");

十、常見問題解答

Q1:如何避免中介者變成"上帝對象"?

  • 職責拆分:創建多個專業中介者(如登錄中介者、支付中介者)
  • 使用狀態模式:讓中介者根據狀態改變行為
  • 結合命令模式:將操作封裝為命令對象

Q2:中介者模式如何支持異步?

class AsyncMediator {private Executor executor = Executors.newCachedThreadPool();public void mediate(Runnable task) {executor.execute(task);}
}

Q3:如何處理組件間的雙向通信?

在中介者中實現回調機制:

interface Callback {void onComplete(Object result);
}class ComponentA {void request(Mediator mediator, Callback callback) {mediator.processRequest(this, callback);}
}class Mediator {void processRequest(ComponentA comp, Callback callback) {// 處理請求...callback.onComplete(result);}
}

如果你覺得文章對你有幫助的話,請幫忙點點關注吧!謝謝啦

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

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

相關文章

ArcGIS應用指南:基于網格與OD成本矩陣的交通可達性分析

隨著城市化進程的加速,交通系統的效率和公平性日益成為影響居民生活質量的關鍵因素之一。在這一背景下,如何科學評估城市區域內的交通可達性,成為了城市規劃、交通管理和公共政策制定中的重要議題。作為中國東南沿海的重要港口城市,廈門以其獨特的地理優勢和快速的城市發展…

基于NXP例程學習CAN UDS刷寫流程

文章目錄 前言1.概述1.1 診斷報文 2.協議數據單元(N_PDU)2.1 尋址信息&#xff08;N_AI&#xff09;2.1.1 物理尋址2.1.2 功能尋址2.1.3 常規尋址&#xff08;Normal addressing&#xff09;2.1.4 常規固定尋址&#xff08;Normal fixed addressing&#xff09;2.1.5 擴展尋址&…

近期手上的一個基于Function Grap(類AWS的Lambda)小項目的改造引發的思考

函數式Function是云計算里最近幾年流行起來的新的架構和模式&#xff0c;因為它不依賴云主機&#xff0c;非常輕量&#xff0c;按需使用&#xff0c;甚至是免費使用&#xff0c;特別適合哪種數據同步&#xff0c;數據轉發&#xff0c;本身不需要保存數據的業務場景&#xff0c;…

什么是 SQL 注入?如何防范?

什么是 SQL 注入?如何防范? 1. SQL 注入概述 1.1 基本定義 SQL 注入(SQL Injection)是一種通過將惡意SQL 語句插入到應用程序的輸入參數中,從而欺騙服務器執行非預期SQL命令的攻擊技術。攻擊者可以利用此漏洞繞過認證、竊取數據甚至破壞數據庫。 關鍵結論:SQL 注入是O…

高德地圖應用OceanBase單元化構建下一代在線地圖服務

IEEE International Conference on Data Engineering (ICDE) 是數據庫和數據工程領域的頂級學術會議之一&#xff08;與SIGMOD、VLDB并成為數據庫三大頂會&#xff09;&#xff0c;自1984年首次舉辦以來&#xff0c;每年舉辦一次。ICDE涵蓋廣泛的主題&#xff0c;包括數據庫系統…

Vue3中Element-Plus中el-input及el-select 邊框樣式

如果不需要顯示下邊框&#xff0c;純無邊框直接將 【border-bottom: 1px solid #C0C4CC; 】注掉或去掉即可。 正常引用組件使用即可&#xff0c;無須自定義樣式&#xff0c;最終效果CSS樣式。 <style scoped> /* 輸入框的樣式 */ :deep(.el-input__wrapper) { box-sha…

如何做好一份技術文檔:從信息孤島到知識圖譜的進階之路

如何做好一份技術文檔&#xff1a;從信息孤島到知識圖譜的進階之路 在軟件開發的漫長征程中&#xff0c;技術文檔如同隱藏在代碼叢林中的路標&#xff0c;不僅指引著開發團隊的前行方向&#xff0c;更在產品迭代的歲月里構筑起知識傳承的橋梁。一份優質的技術文檔&#xff0c;既…

Docker Compose使用自定義用戶名密碼啟動Redis

通常我們使用下面的命令來啟動 redis 容器&#xff0c;此時連接 Redis 的時候是不需要用戶認證的 sudo docker run -d --name my-redis -p 6379:6379 redis此時我們可以使用 redis-server --requirepass "mypassword" 來指定默認用戶&#xff08;default&#xff09…

1.什么是node.js、npm、vue

一、Node.js 是什么&#xff1f; &#x1f63a; 定義&#xff1a; Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行時環境&#xff0c;讓你可以在瀏覽器之外運行 JavaScript 代碼&#xff0c;主要用于服務端開發。 &#x1f63a;從計算機底層說&#xff1a;什么是“運…

如何在 Vue.js 中集成 Three.js —— 創建一個旋轉的 3D 立方體

在這篇文章中&#xff0c;我將向大家展示如何將 Three.js 與 Vue.js 結合&#xff0c;創建一個簡單的 3D 場景&#xff0c;并展示一個旋轉的立方體。通過這個簡單的示例&#xff0c;你將學習到如何在 Vue 項目中集成 Three.js&#xff0c;以及如何創建動態的 3D 內容。 1. 安裝…

DeepSeek?R1-0528 重磅升級:螞蟻百寶箱免費、無限量調用

DeepSeek?R1-0528 重磅升級&#xff1a;螞蟻百寶箱免費、無限量調用 端午假期前一天&#xff0c;DeepSeek?R1 更新到了 0528 版本&#xff01; 官方說明&#xff1a;0528 版本在深度思考與推理能力方面顯著增強——在數學、編程與通用邏輯等多項基準測評中&#xff0c;表現已…

RS232轉Profinet網關在檢漏儀與西門子PLC里的應用

RS232轉Profinet網關在檢漏儀與西門子PLC里的應用 在工業自動化和控制領域&#xff0c;設備間的高效通信至關重要。RS232轉Profinet網關作為一種關鍵的轉換工具&#xff0c;能夠將傳統的RS232接口設備接入現代化的Profinet網絡&#xff0c;從而實現數據的無縫傳輸和設備的遠程…

jenkins-jenkins簡介

一、簡介 jenkins是一個可擴展的持續集成引擎。持續集成&#xff0c;也就是通常所說的CI&#xff08;Continues Integration&#xff09;&#xff0c;可以說是現代軟件技術開發的基礎。持續集成是一種軟件開發實踐&#xff0c; 即團隊開發成員經常集成他們的工作&#xff0c;通…

vue發版html 生成打包到docker鏡像進行發版

將Vue項目打包成Docker鏡像部署主要分為以下幾個步驟&#xff1a; 1. Vue項目打包? 執行npm run build生成dist文件夾&#xff0c;包含靜態資源文件 注意檢查index.html中資源引用路徑是否正確&#xff08;避免絕對路徑問題&#xff09; 2. 編寫Dockerfile Copy Code FROM…

掃地機器人苦尋新引擎,大疆們卻已攻入腹地

原創 科技新知 前沿科技組 作者丨江籬 編輯丨櫻木、九黎 競爭激烈的掃地機器人賽道&#xff0c;迎來了新玩家。 據近日相關報道&#xff0c;大疆掃地機器人產品已開始量產&#xff0c;預計將于6月份發布。消息稱大疆研發掃地機器人已超過四年&#xff0c;即將上市的產品是掃…

【C++】22. 紅黑樹封裝實現Mymap和Myset

上一章節我們實現了紅黑樹&#xff0c;這一章節我們就用紅黑樹封裝來實現一個我們自己的map和set 1. 源碼及框架分析 SGI-STL 3.0版本的源代碼中&#xff0c;map和set的實現主要分布在若干頭文件中&#xff0c;這些頭文件構成了這兩個容器的完整實現架構&#xff1a; 核心頭文…

02_redis分布式鎖原理

文章目錄 一、redis如何實現分布式鎖1. 使用 SETNX 命令2. 設置過期時間3. 釋放鎖4. 注意事項5. 示例代碼二、Java中分布式鎖如何設置超時時間1. Redis分布式鎖2. 基于Zookeeper的分布式鎖3. 基于數據庫的分布式鎖注意事項一、redis如何實現分布式鎖 Redis 實現分布式鎖是一種…

酷派Cool20/20S/30/40手機安裝Play商店-谷歌三件套-GMS方法

酷派Cool系列主打低端市場&#xff0c;系統無任何GMS程序&#xff0c;也不支持直接開啟或者安裝谷歌服務等功能&#xff0c;對于國內部分經常使用谷歌服務商店的小伙伴非常不友好。涉及機型有酷派Cool20/Cool20S /30/40/50/60等旗下多個設備。好在這些機型運行的系統都是安卓11…

技術為器,服務為本:AI時代的客服價值重構

在智能化浪潮中&#xff0c;大語言模型的出現為客戶服務行業注入了全新動能。然而技術創新的價值不在于技術本身&#xff0c;而在于其賦能服務的深度與廣度。AI對于我們來說&#xff0c;如同發動機之于汽車&#xff0c;重要的不是引擎參數&#xff0c;而是整車帶給用戶的駕駛體…

技術創新如何賦能音視頻直播行業?

在全球音視頻直播行業的快速發展中&#xff0c;技術的持續創新始終是推動行業進步的核心動力。作為大牛直播SDK的開發者&#xff0c;我很榮幸能分享我們公司如何從產品的維度出發&#xff0c;精準把握市場需求&#xff0c;并不斷推動產品的發展&#xff0c;以滿足不斷變化的行業…