中介者模式:解耦對象間復雜交互的設計模式

中介者模式:解耦對象間復雜交互的設計模式

一、模式核心:用中介者統一管理對象交互,避免兩兩直接依賴

當系統中多個對象之間存在復雜的網狀交互時(如 GUI 界面中按鈕、文本框、下拉框的聯動),對象間直接調用會導致關系混亂、難以維護。

中介者模式(Mediator Pattern) 通過引入一個中介者對象(Mediator),將對象間的直接交互轉換為與中介者的單向交互。所有對象只需與中介者通信,由中介者協調處理交互邏輯,從而實現對象間的松耦合。核心解決:

  • 交互復雜性:避免對象間形成復雜的依賴網絡,降低系統復雜度。
  • 可維護性:交互邏輯集中在中介者中,修改時只需調整中介者,無需修改多個對象。
  • 擴展性:新增對象時只需實現與中介者的交互,不影響現有對象間的邏輯。

核心思想與 UML 類圖

中介者模式包含以下角色:

  1. 中介者接口(Mediator):定義對象間交互的接口,如接收消息、分發消息。
  2. 具體中介者(Concrete Mediator):實現中介者接口,協調具體同事對象的交互。
  3. 同事類(Colleague):依賴中介者,通過中介者間接交互,不直接調用其他同事。

PlantUML Diagram

二、核心實現:GUI 界面組件的交互協調

1. 定義中介者接口

public interface Mediator {  void notify(Object sender, String event); // 接收消息(發送者、事件類型)  
}  

2. 實現具體中介者(處理組件聯動)

public class UIMediator implements Mediator {  private Button button;  private TextBox textBox;  private Dropdown dropdown;  // 設置中介者關聯的組件  public void setButton(Button button) {  this.button = button;  }  public void setTextBox(TextBox textBox) {  this.textBox = textBox;  }  public void setDropdown(Dropdown dropdown) {  this.dropdown = dropdown;  }  @Override  public void notify(Object sender, String event) {  if (sender == button && "click".equals(event)) {  // 按鈕點擊時,獲取文本框內容并更新下拉框  String text = textBox.getText();  dropdown.setSelectedItem(text);  System.out.println("按鈕點擊:設置下拉框選項為 " + text);  } else if (sender == dropdown && "select".equals(event)) {  // 下拉框選擇時,清空文本框  textBox.clear();  System.out.println("下拉框選擇:清空文本框");  }  }  
}  

3. 定義抽象同事類(組件基類)

public abstract class UIComponent {  protected Mediator mediator;  public void setMediator(Mediator mediator) {  this.mediator = mediator;  }  protected void sendEvent(String event) {  if (mediator != null) {  mediator.notify(this, event); // 通過中介者發送事件  }  }  
}  

4. 實現具體同事類(按鈕、文本框、下拉框)

按鈕組件
public class Button extends UIComponent {  public void onClick() {  System.out.println("按鈕被點擊");  sendEvent("click"); // 發送點擊事件給中介者  }  
}  
文本框組件
public class TextBox extends UIComponent {  private String text;  public String getText() {  return text;  }  public void setText(String text) {  this.text = text;  }  public void clear() {  text = "";  System.out.println("文本框已清空");  }  
}  
下拉框組件
public class Dropdown extends UIComponent {  private String selectedItem;  public void setSelectedItem(String item) {  this.selectedItem = item;  System.out.println("下拉框選中:" + selectedItem);  }  
}  

5. 客戶端初始化中介者與組件

public class ClientDemo {  public static void main(String[] args) {  // 創建中介者和組件  UIMediator mediator = new UIMediator();  Button button = new Button();  TextBox textBox = new TextBox();  Dropdown dropdown = new Dropdown();  // 組件關聯中介者  button.setMediator(mediator);  textBox.setMediator(mediator);  dropdown.setMediator(mediator);  // 中介者關聯組件(雙向綁定)  mediator.setButton(button);  mediator.setTextBox(textBox);  mediator.setDropdown(dropdown);  // 模擬用戶操作:文本框輸入內容,按鈕點擊觸發聯動  textBox.setText("Option A");  button.onClick(); // 按鈕點擊,通過中介者更新下拉框  System.out.println("\n模擬下拉框選擇操作:");  mediator.notify(dropdown, "select"); // 下拉框選擇,通過中介者清空文本框  }  
}  

輸出結果

按鈕被點擊  
按鈕點擊:設置下拉框選項為 Option A  
下拉框選中:Option A  模擬下拉框選擇操作:  
下拉框選擇:清空文本框  
文本框已清空  

三、框架與源碼中的中介者實踐

1. Spring MVC 的 Controller 作為中介者

在 Spring MVC 中,Controller 作為中介者協調 ModelView 的交互:

  • View(如 JSP)發送請求到 Controller
  • Controller 調用 Model 處理業務邏輯,再將結果返回給 View
@Controller  
public class UserController {  @Autowired  private UserService userService; // Model 層  @GetMapping("/user/{id}")  public String getUser(@PathVariable int id, Model model) {  User user = userService.getUser(id);  model.addAttribute("user", user); // 中介者傳遞數據到 View  return "user.jsp"; // 中介者決定返回視圖  }  
}  

2. Android 的 Activity 作為中介者

Android 中 Activity 作為中介者管理界面組件(ButtonEditText 等)的交互:

  • 組件通過 setOnClickListener 注冊事件到 Activity
  • Activity 處理事件并協調組件狀態更新。
public class MainActivity extends AppCompatActivity {  private EditText editText;  private TextView textView;  @Override  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  editText = findViewById(R.id.edit_text);  textView = findViewById(R.id.text_view);  findViewById(R.id.button).setOnClickListener(v -> {  String text = editText.getText().toString();  textView.setText("輸入內容:" + text); // 中介者協調組件交互  });  }  
}  

3. Java Swing 的 Event Dispatch Thread

Swing 通過事件分發線程(中介者)處理組件事件,避免組件間直接通信:

  • 按鈕點擊事件由 Event Dispatch Thread 接收并分發給注冊的監聽器。

四、避坑指南:正確使用中介者模式的 3 個要點

1. 避免中介者過度復雜

若中介者承擔過多職責,會形成 “上帝對象”。可將中介者拆分為多個專用中介者(如訂單中介者、支付中介者),或引入分層結構(如中介者 + 協調者)。

2. 平衡中介者與同事的職責

同事類應盡量保持簡單,僅包含自身狀態和基本操作,復雜邏輯集中在中介者中。若同事類需要頻繁調用中介者,需檢查是否違反單一職責原則。

3. 區分中介者模式與觀察者模式

  • 中介者模式:對象間通過中介者間接交互,形成星型結構(非廣播式)。
  • 觀察者模式:主題與觀察者是一對多的依賴關系,觀察者被動接收通知(廣播式)。

六、總結:何時該用中介者模式?

適用場景核心特征典型案例
對象間網狀交互多個對象間存在復雜直接調用GUI 界面組件聯動、分布式系統節點通信
系統重構解耦遺留系統中對象間緊耦合,需簡化依賴微服務間消息路由、legacy 系統改造
集中式邏輯管理需要將交互邏輯集中管理與維護工作流引擎、交易系統規則引擎

中介者模式通過 “中心化管理” 的設計,有效降低了對象間的耦合度,提升了系統的可維護性和擴展性。下一篇我們將探討訪問者模式,解析如何分離數據結構與操作,敬請期待!

擴展思考:中介者模式的缺點

  • 中介者單點風險:中介者故障會導致整個系統交互失效,需通過冗余設計或分布式中介者緩解。
  • 調試難度增加:交互邏輯集中在中介者中,需借助日志或調試工具追蹤消息流程。

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

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

相關文章

豆包桌面版 1.47.4 可做瀏覽器,免安裝綠色版

自己動手升級更新辦法: 下載新版本后安裝,把 C:\Users\用戶名\AppData\Local\Doubao\Application 文件夾的文件,拷貝替換 DoubaoPortable\App\Doubao 文件夾的文件,就升級成功了。 再把安裝的豆包徹底卸載就可以。 桌面版比網頁版…

Android PackageManagerService(PMS)框架深度解析

目錄 一、概念與核心作用 二、技術架構與模塊組成 1. 分層架構 1.1 應用層架構細節 1.2 Binder接口層實現 1.3 PMS核心服務層 1.4 底層支持層實現 2. 核心模塊技術要點與工作流程 2.1 PackageParser 2.2 Settings 2.3 PermissionManager 2.4 Installer 2.5 ComponentM…

TensorFlow深度學習實戰(14)——循環神經網絡詳解

TensorFlow深度學習實戰(14)——循環神經網絡詳解 0. 前言1. 基本循環神經網絡單元1.1 循環神經網絡工作原理1.2 時間反向傳播1.3 梯度消失和梯度爆炸問題2. RNN 單元變體2.1 長短期記憶2.2 門控循環單元2.3 Peephole LSTM3. RNN 變體3.1 雙向 RNN3.2 狀態 RNN4. RNN 拓撲結構…

PySide6 GUI 學習筆記——常用類及控件使用方法(常用類矩陣QRectF)

文章目錄 類描述構造方法主要方法1. 基礎屬性2. 邊界操作3. 幾何運算4. 坐標調整5. 轉換方法6. 狀態判斷 類特點總結1. 浮點精度:2. 坐標系統:3. 有效性判斷:4. 幾何運算:5. 類型轉換:6. 特殊處理: 典型應用…

Electron主進程渲染進程間通信的方式

在 Electron 中,主進程和渲染進程之間的通信主要通過 IPC(進程間通信)機制實現。以下是幾種常見的通信方式: 1. 渲染進程向主進程發送消息(單向) 渲染進程可以通過 ipcRenderer.send 向主進程發送消息&am…

【C++基礎知識】C++類型特征組合:`disjunction_v` 和 `conjunction_v` 深度解析

這兩個模板是C17引入的類型特征組合工具,用于構建更復雜的類型判斷邏輯。下面我將從技術實現到實際應用進行全面剖析: 一、基本概念與C引入版本 1. std::disjunction_v (邏輯OR) 引入版本:C17功能:對多個類型特征進行邏輯或運算…

私有知識庫 Coco AI 實戰(二):攝入 MongoDB 數據

在之前的文章中,我們介紹過如何使用《 Logstash 遷移 MongoDB 數據到 Easyseach》,既然 Coco AI 后臺數據存儲也使用 Easysearch,我們能否直接把 MongoDB 的數據遷移到 Coco AI 的 Easysearch,使用 Coco AI 對數據進行檢索呢&…

sql server 與navicat測試后,連接qt

先用Navicat測試和sql的連通性,Navicat和sql連通之后,qt也能和sql連通了。 Navicat和Sqlserver Management 能連上,項目無法連接本地 Navicat 連接SQLServer 數據庫 QT國內鏡像網站 Navicat連接SqlServer的問題點 Sql Server的基本配置以及使…

2025年3月電子學會青少年機器人技術(六級)等級考試試卷-理論綜合

青少年機器人技術等級考試理論綜合試卷(六級) 分數:100 題數:30 一、單選題(共20題,共80分) 1. 2025年初,中國科技初創公司深度求索在大模型領域迅速崛起,其開源的大模型成為全球AI領域的焦…

spark local模式搭建運行示例

Apache Spark 是一個強大的分布式計算框架,但在本地模式下,它也可以作為一個單機程序運行,非常適合開發和測試階段。以下是一個簡單的示例,展示如何在本地模式下搭建和運行 Spark 程序。 一、環境準備 安裝 Java Spark 需要 Java…

【人工智能】解鎖 AI 潛能:DeepSeek 大模型遷移學習與特定領域微調的實踐

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 隨著大型語言模型(LLMs)的快速發展,遷移學習與特定領域微調成為提升模型性能的關鍵技術。本文深入探討了 DeepSeek 大模型在遷移學習中的…

視頻智能分析平臺EasyCVR無線監控:全流程安裝指南與功能應用解析

在當今數字化安防時代,無線監控系統的安裝與調試對于保障各類場所的安全至關重要。本文將結合EasyCVR視頻監控的強大功能,為您詳細闡述監控系統安裝過程中的關鍵步驟和注意事項,幫助您打造一個高效、可靠的監控解決方案。 一、調試物資準備與…

【k8s系列7-更新中】kubeadm搭建Kubernetes高可用集群-三主兩從

主機準備 結合前面的章節,這里需要5臺機器,可以先創建一臺虛擬機作為基礎虛擬機。優先把5臺機器的公共部分優先在一臺機器上配置好 1、配置好靜態IP地址 2、主機名宇IP地址解析 [root@localhost ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost…

【Java后端】MyBatis 與 MyBatis-Plus 如何防止 SQL 注入?從原理到實戰

在日常開發中,SQL 注入是一種常見但危害巨大的安全漏洞。如果你正在使用 MyBatis 或 MyBatis-Plus 進行數據庫操作,這篇文章將帶你系統了解:這兩個框架是如何防止 SQL 注入的,我們又該如何寫出安全的代碼。 什么是 SQL 注入&#…

數據分析案例:醫療健康數據分析

目錄 數據分析案例:醫療健康數據分析1. 項目背景2. 數據加載與預處理2.1 加載數據2.2 數據清洗3. 探索性數據分析(EDA)3.1 再入院率概覽3.2 按年齡分組的再入院率3.3 住院時長與再入院4. 特征工程與可視化5. 模型構建與評估5.1 數據劃分5.2 訓練邏輯回歸5.3 模型評估6. 業務…

3臺CentOS虛擬機部署 StarRocks 1 FE+ 3 BE集群

背景:公司最近業務數據量上去了,需要做一個漏斗分析功能,實時性要求較高,mysql已經已經不在適用,做了個大數據技術棧選型調研后,決定使用StarRocks StarRocks官網:StarRocks | A High-Performa…

軟件設計師/系統架構師---計算機網絡

概要 什么是計算機網絡? 計算機網絡是指將多臺計算機和其他設備通過通信線路互聯,以便共享資源和信息的系統。計算機網絡可以有不同的規模,從家庭網絡到全球互聯網。它們可以通過有線(如以太網)或無線(如W…

1.5軟考系統架構設計師:架構師的角色與能力要求 - 超簡記憶要點、知識體系全解、考點深度解析、真題訓練附答案及解析

超簡記憶要點 角色職責 需求規劃→架構設計→質量保障 能力要求 技術(架構模式/性能優化) 業務(模型抽象→技術方案) 管理(團隊協作/風險控制) 知識體系 基礎:CAP/設計模式/網絡協議案例&am…

基于STM32的汽車主門電動窗開關系統設計方案

芯片和功能模塊選型 主控芯片 STM32F103C8T6:基于 ARM Cortex - M3 內核,有豐富的 GPIO 接口用于連接各類外設,具備 ADC 模塊可用于電流檢測,還有 CAN 控制器方便實現 CAN 總線通信。它資源豐富、成本低,適合學生進行 DIY 項目開發。按鍵模塊 輕觸按鍵:用于控制車窗的自…

第十三屆藍橋杯 2022 C/C++組 修剪灌木

目錄 題目: 題目描述: 題目鏈接: 思路: 核心思路: 思路詳解: 代碼: 代碼詳解: 題目: 題目描述: 題目鏈接: P8781 [藍橋杯 2022 省 B] 修…