設計模式15:中介者模式

?系列總鏈接:《大話設計模式》學習記錄_net 大話設計-CSDN博客

1.概述

? ? ?中介者模式(Mediator Pattern)是一種行為設計模式,旨在通過一個中介對象來封裝一系列對象之間的交互方式,從而減少這些對象間的直接依賴。在該模式下,各個組件(同事)不再直接相互通信,而是通過中介者進行間接溝通,這極大地降低了系統的耦合度。具體來說,中介者定義了同事類之間的通信接口,并負責協調同事對象之間的交互邏輯。每個同事類都知道其對應的中介者對象,但并不直接與其他同事類交互。

2.結構與實現

結構:

  • Mediator(抽象中介者):定義同事類之間的通信接口。
  • ConcreteMediator(具體中介者):實現了抽象中介者的接口,并協調各同事對象之間的交互。
  • Colleague Class(抽象同事類):每個同事類都知道其對應的中介者對象,并且可以通過中介者發送消息給其他同事。
  • ConcreteColleague(具體同事類):實現了抽象同事類,負責發送和接收消息。

實現:

假設我們要創建一個簡單的聊天應用程序,用戶之間通過ChatRoom(中介者)進行交流。

代碼目錄結構為:

首先,定義ChatRoom作為抽象中介者:

ChatRoom.h:

#ifndef CHATROOM_H
#define CHATROOM_H#include <QString>class User; // 前向聲明User類,避免循環依賴// 抽象中介者:定義同事類之間的通信接口。
class ChatRoom {
public:virtual void sendMessage(const QString& message, User* user) = 0; // 發送消息的純虛函數
};#endif // CHATROOM_H

ConcreteChatRoom.h

#ifndef CONCRETECHATROOM_H
#define CONCRETECHATROOM_H#include "ChatRoom.h"
#include <QList> // Qt容器類,用于存儲用戶列表
#include "User.h"// 具體中介者:實現了抽象中介者的接口,并協調各同事對象之間的交互。
class ConcreteChatRoom : public ChatRoom {
private:QList<User*> users; // 存儲所有用戶的列表
public:// 添加用戶到聊天室中void addUser(User* user) {users.append(user);}// 實現發送消息的功能void sendMessage(const QString& message, User* user) override;
};#endif // CONCRETECHATROOM_H

ConcreteChatRoom.cpp

#include "ConcreteChatRoom.h"
#include "User.h"
#include <QDebug>// 實現sendMessage方法,遍歷所有用戶并轉發消息給其他用戶(除了發送者)
void ConcreteChatRoom::sendMessage(const QString& message, User* user)
{// 遍歷所有用戶for (User* u : users){if(u != user) { // 如果不是消息的發送者,則轉發消息u->receiveMessage(message); // 調用接收消息的方法}}
}

User.h

#ifndef USER_H
#define USER_H#include <QString>
#include "ChatRoom.h" // 包含中介者接口// 抽象同事類:每個同事類都知道其對應的中介者對象,并且可以通過中介者發送消息給其他同事。
class User {
protected:ChatRoom* chatroom; // 指向中介者的指針QString name; // 用戶名
public:// 構造函數,初始化中介者和用戶名User(ChatRoom* chatroom, const QString& name): chatroom(chatroom), name(name) {}// 發送消息的方法virtual void sendMessage(const QString& message);// 接收消息的方法virtual void receiveMessage(const QString& message);// 獲取用戶名的方法QString getName() const { return name; }
};#endif // USER_H

User.cpp

#include "User.h"
#include "ConcreteChatRoom.h" // 包含具體中介者的頭文件
#include <QDebug>// 發送消息的實現
void User::sendMessage(const QString& message) {qDebug() << getName() << " sends: " << message; // 打印發送者信息chatroom->sendMessage(message, this); // 通過中介者發送消息
}// 接收消息的實現
void User::receiveMessage(const QString& message) {qDebug() << getName() << " receives: " << message; // 打印接收者信息
}

main.cpp:

#include <QCoreApplication>
#include "ConcreteChatRoom.h" // 包含具體中介者
#include "User.h" // 包含同事類int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 創建一個具體的中介者實例ConcreteChatRoom chatRoom;// 創建兩個用戶并關聯到同一個中介者User user1(&chatRoom, "Alice");User user2(&chatRoom, "Bob");User user3(&chatRoom, "Tom");// 將用戶添加到聊天室中chatRoom.addUser(&user1);chatRoom.addUser(&user2);chatRoom.addUser(&user3);// 用戶發送消息user1.sendMessage("Hello Bob!");//user2.sendMessage("Hi Alice!");return a.exec();
}

運行效果:

"Alice"  sends:  "Hello Bob!"
"Bob"  receives:  "Hello Bob!"
"Tom"  receives:  "Hello Bob!"

3.應用

中介者模式非常適合用于以下場景:

  • GUI框架中,例如Qt,其中各種控件可能需要相互通訊但又不希望直接依賴對方。
  • 多模塊或分布式系統中,各個模塊或節點之間的通信可以由中介者集中管理。
  • 狀態管理器或控制器層,用于管理不同視圖組件的狀態更新和事件分發。

4.優缺點及適用環境

優點:

  • 減少依賴:減少了同事對象之間的直接依賴,降低了系統的耦合度。
  • 簡化交互:通過中介者集中管理對象間的交互,使得代碼更加清晰易讀。
  • 易于擴展:新增同事對象時不需要修改現有的同事對象,只需調整中介者即可。

缺點:

  • 復雜性增加:如果中介者變得過于復雜,可能會成為系統的瓶頸,同時也會增加維護成本。
  • 單一職責原則:如果中介者承擔過多的責任,可能會導致其變得龐大且難以管理。

應用環境:

  • 當系統中有大量對象需要相互通信,但你希望避免它們之間的直接引用時。
  • 對于那些希望通過引入中介者來提高模塊獨立性的系統來說,中介者模式是一個很好的選擇。
  • 在開發復雜的GUI應用程序時,使用中介者模式可以幫助更好地管理和控制組件之間的交互。

? ? ? 通過職責鏈模式,我們可以構建更加靈活、易于擴展的應用程序,尤其是在涉及多種類型的請求處理時。然而,在使用此模式時也應注意其可能帶來的性能損耗和復雜性的增加。

5.舉一反三

中介者模式因其能有效減少對象間的直接依賴和簡化復雜的交互邏輯,適用于多種場景。以下是一些可以應用中介者模式的具體例子及其應用場景:

1. GUI應用程序

在Qt或其他GUI框架中,組件(如按鈕、文本框等)之間的交互往往比較復雜。使用中介者模式可以幫助管理這些交互,避免組件間直接相互引用。

  • 示例:在一個表單中,某些輸入框的可用性可能取決于其他輸入框的內容或狀態。例如,選擇“是否需要發票”復選框后,相關的稅號輸入框才變為可編輯狀態。通過引入一個中介者來監聽這些事件并更新相應的UI組件狀態,可以使代碼更加清晰且易于維護。

2. 分布式系統中的模塊通信

在分布式系統或微服務架構中,各個服務或模塊之間需要進行通信。為了避免服務之間的直接依賴,可以通過引入中介者(如消息隊列或API網關)來解耦這些服務。

  • 示例:在一個電商系統中,訂單服務、庫存服務和支付服務都需要相互通信以完成下單流程。使用中介者模式可以確保這些服務不直接相互調用,而是通過中介者傳遞消息,從而提高了系統的靈活性和可擴展性。

3. 游戲開發中的物體交互

在游戲中,不同游戲物體(如角色、敵人、道具等)之間的交互非常頻繁。使用中介者模式可以幫助管理這些交互,特別是當涉及到多個物體同時對同一事件作出反應時。

  • 示例:在一個多人在線游戲中,當玩家撿起一件裝備時,不僅該玩家的狀態會發生變化,其他玩家也可能看到這一變化。通過引入一個中介者來協調這些狀態更新,可以有效地管理復雜的同步邏輯。

4. 狀態管理和事件分發

在具有復雜狀態的應用程序中,比如企業級應用或大型網站,狀態的變化可能會影響到多個視圖或組件。使用中介者模式可以幫助集中管理這些狀態變化,并通知相關聯的視圖或組件進行更新。

  • 示例:在一個具有多個視圖的單頁應用(SPA)中,用戶登錄狀態的變化可能會影響導航欄、側邊欄等多個地方。通過使用中介者來處理這種狀態變化,并向所有相關視圖廣播通知,可以使狀態管理更加簡潔高效。

5. 智能家居控制系統

智能家居設備(如燈光、溫度控制器、安全系統等)通常需要根據環境變化或其他設備的狀態自動調整其行為。使用中介者模式可以使得這些設備之間的交互更加靈活和獨立。

  • 示例:當智能門鎖檢測到有人進入房屋時,它可以通過中介者通知室內照明系統開啟特定區域的燈光,并告知溫控器調整室溫。這種方式既實現了設備間的解耦,又保證了響應的及時性和準確性。

總之,中介者模式非常適合用于那些需要管理多個對象間復雜交互的場景,特別是在希望減少對象間直接依賴、提高模塊獨立性以及簡化交互邏輯的情況下。通過合理地應用中介者模式,可以構建出更加靈活、易于維護和擴展的軟件系統。

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

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

相關文章

golang常用庫之-swaggo/swag根據注釋生成接口文檔

golang常用庫之-swaggo/swag庫根據注釋生成接口文檔 什么是swaggo/swag github&#xff1a;https://github.com/swaggo/swag 參考文檔&#xff1a;https://golang.halfiisland.com/community/pkgs/web/swag.html#%E4%BD%BF%E7%94%A8 swaggo/swag 是 Swagger API 2.0 在 go 語…

爬取網站內容轉為markdown 和 html(通常模式)

我們遇到一些自己喜歡內容&#xff0c;想保存下來&#xff0c;手動復制粘貼很麻煩&#xff0c;我們使用 python 來爬取這些內容。 一、代碼 downlod.py import os import requests from bs4 import BeautifulSoup from urllib.parse import urljoin# 目標網頁&#xff08;可…

. Spring MVC

&#xff08;1&#xff09;MVC 設計模式 Model&#xff08;模型&#xff09;&#xff1a;負責存儲數據和業務邏輯。在 Spring MVC 中&#xff0c;模型通常是 JavaBean&#xff0c;用于封裝數據。 View&#xff08;視圖&#xff09;&#xff1a;負責展示數據給用戶。可以是 JSP…

高效執行自動化用例:分布式執行工具pytest-xdist實戰!

01、聲明 在介紹pytest-xdist時&#xff0c;不講任何原理&#xff0c;需要看原理的請移至官方&#xff1a;https://pypi.org/project/pytest-xdist/ 當我們自動化測試用例非常多的時候&#xff0c; 一條條按順序執行會非常慢&#xff0c;pytest-xdist的出現就是為了讓自動化測…

【ISO 14229-1:2023 UDS診斷全量測試用例清單系列:第十八節】

ISO 14229-1:2023 UDS診斷服務測試用例全解析&#xff08;ResponseOnEvent_0x86服務&#xff09; 作者&#xff1a;車端域控測試工程師 更新日期&#xff1a;2025年02月14日 關鍵詞&#xff1a;UDS協議、0x86服務、事件響應、ISO 14229-1:2023、ECU測試 一、服務功能概述 0x86…

deepseek多列數據對比,聯想到excel的高級篩選功能

目錄 1 業務背景 ?2 deepseek提示詞輸入 ?3 聯想分析 4 EXCEL高級搜索 1 業務背景 系統上線的時候經常會遇到一個問題&#xff0c;系統導入的數據和線下的EXCEL數據是否一致&#xff0c;如果不一致&#xff0c;如何快速找到差異值&#xff0c;原來腦海第一反應就是使用公…

TailwindCss的vue3安裝使用

按照官網的安裝教程&#xff0c;屬性最后無法生效&#xff0c;這是自我改良版&#xff0c;添加了額外步驟&#xff0c;但是每次引入新的tailwindcss屬性 需要重新跑一次項目 npm下載tailwindcss npm install -D tailwindcss npx初始化tailwind配置 npx tailwindcss init 此時根…

個人博客測試報告

一、項目背景 個人博客系統采用前后端分離的方法來實現&#xff0c;同時使用了數據庫來存儲相關的數據&#xff0c;同時將其部署到云服務器上。前端主要有四個頁面構成&#xff1a;登錄頁、列表頁、詳情頁以及編輯頁&#xff0c;以上模擬實現了最簡單的個人博客系統。其結合后…

Python----數據結構(單鏈表:節點,是否為空,長度,遍歷,添加,刪除,查找)

一、鏈表 鏈表是一種線性數據結構&#xff0c;由一系列按特定順序排列的節點組成&#xff0c;這些節點通過指針相互連接。每個節點包含兩部分&#xff1a;元素和指向下一個節點的指針。其中&#xff0c;最簡單的形式是單向鏈表&#xff0c;每個節點含有一個信息域和一個指針域&…

夜鶯監控發布 v8.beta5 版本,優化 UI,新增接口認證方式便于鑒權

以防讀者不了解夜鶯&#xff0c;開頭先做個介紹&#xff1a; 夜鶯監控&#xff0c;英文名字 Nightingale&#xff0c;是一款側重告警的監控類開源項目。類似 Grafana 的數據源集成方式&#xff0c;夜鶯也是對接多種既有的數據源&#xff0c;不過 Grafana 側重在可視化&#xff…

什么是Embedding、RAG、Function calling、Prompt engineering、Langchain、向量數據庫? 怎么使用

什么是Embedding、RAG、Function calling、Prompt engineering、Langchain、向量數據庫? 怎么使用 目錄 什么是Embedding、RAG、Function calling、Prompt engineering、Langchain、向量數據庫? 怎么使用Embedding(嵌入)RAG(檢索增強生成)Function calling(函數調用)Pr…

SQLMesh 系列教程5- 詳解SQL模型

本文將詳細介紹 SQLMesh 的 SQL 模型組成要素及其在實際項目中的應用。SQLMesh 是一個強大的數據工程工具&#xff0c;其 SQL 模型由 MODEL DDL、預處理語句、主查詢、后處理語句以及可選的 ON VIRTUAL UPDATE 語句組成。我們將通過一個電商平臺每日銷售報告的實例&#xff0c;…

DeepSeek 接入PyCharm實現AI編程!(支持本地部署DeepSeek及官方DeepSeek接入)

前言 在當今數字化時代&#xff0c;AI編程助手已成為提升開發效率的利器。DeepSeek作為一款強大的AI模型&#xff0c;憑借其出色的性能和開源免費的優勢&#xff0c;成為許多開發者的首選。今天&#xff0c;就讓我們一起探索如何將DeepSeek接入PyCharm&#xff0c;實現高效、智…

從駕駛員到智能駕駛:汽車智能化進程中的控制與仿真技術

在汽車技術持續演進的歷程中&#xff0c;人類駕駛員始終是一個極具研究價值的智能控制系統“原型”。駕駛員通過視覺感知、行為決策與操作執行的閉環控制&#xff0c;將復雜的駕駛任務轉化為車輛的實際動作&#xff0c;同時動態適應道路環境的變化。這一過程不僅體現了高度的自…

Spring Boot項目的基本設計步驟和相關要點介紹

以下是一個關于Spring Boot項目的基本設計步驟和相關要點介紹,我們以一個簡單的示例應用——員工管理系統為例進行說明: 一、項目概述 員工管理系統旨在實現對公司員工信息的有效管理,包括員工基本信息錄入、查詢、更新以及刪除等功能。通過Spring Boot框架來快速搭建后端…

【Java】泛型與集合篇(一)

泛型與集合(一) 泛型泛型的核心作用泛型類型(類)定義與使用類型參數命名約定泛型方法定義與調用與泛型類的區別通配符上界通配符下界通配符有界類型參數類型擦除集合框架核心接口Collection 接口Map 接口Collection 接口操作的常用方法基本操作批量操作數組操作流操作方法L…

HarmonyOS組件之Tabs

Tabs 1.1概念 Tabs 視圖切換容器&#xff0c;通過相適應的頁簽進行視圖頁面的切換的容器組件每一個頁簽對應一個內容視圖Tabs擁有一種唯一的子集元素TabContent 1.2子組件 不支持自定義組件為子組件&#xff0c;僅可包含子組件TabContent&#xff0c;以及渲染控制類型 if/e…

華為FusionCompute虛擬化平臺

一、華為FusionCompute虛擬化套件介紹 華為FusionCompute虛擬化套件是業界領先的虛擬化解決方案&#xff0c;能夠幫助客戶帶來如下的價值&#xff0c;從而大幅提升數據中心基礎設施的效率。 幫助客戶提升數據中心基礎設施的資源利用率&#xff1b;幫助客戶成倍縮短業務上線周期…

使用apt-rdepends制作軟件離線deb安裝包

使用apt-rdepends制作軟件離線deb安裝包 除基礎軟件外&#xff0c;還要獲取軟件依賴包。 依賴包工具安裝 apt-get install apt-rdependsapt-rdepends工具使用 使用apt-rdepends工具&#xff0c;遞歸方式分析軟件依賴&#xff0c;下載軟件包本體&#xff0c;和依賴包。制作時…

【ISO 14229-1:2023 UDS診斷(ECU復位0x11服務)測試用例CAPL代碼全解析⑩】

ISO 14229-1:2023 UDS診斷【ECU復位0x11服務】_TestCase10 作者&#xff1a;車端域控測試工程師 更新日期&#xff1a;2025年02月18日 關鍵詞&#xff1a;UDS診斷協議、ECU復位服務、0x11服務、ISO 14229-1:2023 TC11-010測試用例 用例ID測試場景驗證要點參考條款預期結果TC…