【設計模式-4.8】行為型——中介者模式

說明:本文介紹行為型設計模式之一的中介者模式

定義

中介者模式(Mediator Pattern)又叫作調節者模式或調停者模式。用一個中介對象封裝一系列對象交互,中介者使各對象不需要顯式地互相作用,從而使其耦合松散,而且可以獨立地改變它們之間的交互,屬于行為型設計模式。

(引自《設計模式就該這樣學》P376)

中介者模式簡單來說,就是引入中間層,讓多對多關系,轉為多個一對多關系,圖示如下:

(多對多場景)

在這里插入圖片描述

(引入中間層,轉為多個一對多)

在這里插入圖片描述

這樣符合迪米特法則(指一個軟件實體應當盡可能少地與其他實體發生相互作用),這樣,當一個模塊修改時,就會盡量少地影響其他的模塊。

通訊交友

以兩人通訊為例,如下,

(用戶類,User)

/*** 用戶類*/
public class User {/*** 自己的名字*/private String name;/*** 定義通話對方*/private User friend;public User(String name) {this.name = name;}public String getName() {return name;}/*** 建立連接*/public void connect(User friend) {this.friend = friend;}/*** 說話* 我方說話,調用對方的listen方法*/public void talk(String msg) {friend.listen(msg);}/*** 接聽*/private void listen(String msg) {System.out.println(friend.name + " 對 " + name + " 說:" + msg);}
}

(客戶端使用,進行聊天)

public class Client {public static void main(String[] args) {User zhangsan = new User("zhangsan");User lisi = new User("lisi");zhangsan.connect(lisi);lisi.connect(zhangsan);zhangsan.talk("hello,四哥,我是三哥啊,您最近挺好的啊?");lisi.talk("哦,三哥啊,我以為誰呢,我挺好的,您呢?");}
}

開始通話

在這里插入圖片描述

現在只有兩個人,這種設計看起來沒有問題,但如果有十個人,開一場多人會議,就要在對象內維護一個User集合,而會議人數新增或減少時,要同時改動每個對象中的User集合,這非常繁瑣還容易出問題。

聊天室

基于上面代碼的問題,我們引入一個中間層(聊天室),如下:

(用戶類,User,定義一個所屬聊天室)

/*** 用戶類*/
public class User {/*** 自己的名字*/private String name;/*** 所屬聊天室*/private Chatroom chatRoom;public User(String name) {this.name = name;}public String getName() {return name;}/*** 加入群聊*/public void login(Chatroom chatRoom) {this.chatRoom = chatRoom;chatRoom.register(this);}/*** 群內發言*/public void talk(String msg) {chatRoom.sendMsg(this, msg);}/*** 接收消息*/public void listen(User fromUser, String msg) {System.out.println("【" + this.name + "】的聊天框 【" + fromUser.getName()  + "】說:" + msg);}
}

(聊天室,用來管理群成員,發消息等操作)

import java.util.ArrayList;
import java.util.List;/*** 聊天室*/
public class Chatroom {/*** 群名稱*/private String name;public Chatroom(String name) {this.name = name;}/*** 群內好友*/private List<User> users = new ArrayList<>();/*** 好友加入群聊*/public void register(User user) {this.users.add(user);System.out.println("【系統消息】" + user.getName() + "進入群聊");}/*** 群內發消息*/public void sendMsg(User fromUser, String msg) {users.stream().forEach(user -> user.listen(fromUser, msg));System.out.println("-------------------------------------------------");}
}

(客戶端測試,Client)

public class Client {public static void main(String[] args) {// 創建群,好友Chatroom chatroom = new Chatroom("各位IT界的大佬們");User zhangsan = new User("zhangsan");User lisi = new User("lisi");User wangwu = new User("王五");// 好友加入群聊zhangsan.login(chatroom);lisi.login(chatroom);// 發消息zhangsan.talk("hello,四哥,群里就你一個人啊");lisi.talk("是啊,把五哥拉進來");// 拉人進群wangwu.login(chatroom);// 發消息zhangsan.talk("哇,五哥來了");wangwu.talk("哥幾個,怎么說");}
}

怎么樣,這樣設計是不是好多了,結構一下就穩定了,無論群成員增加還是減少,現有代碼都不用改動。

在這里插入圖片描述

使用場景

在《設計模式就該這樣學》(P378)這本書中,提到狀態模式適用于以下場景:

(1)系統中對象之間存在復雜的引用關系,產生的相互依賴關系結構混亂且難以理解。

(2)交互的公共行為,如果需要改變行為,則可以增加新的中介者類。

中介者模式,在Java三層結構開發中就有體現,Service層不會直接訪問數據庫,而是抽出DAO層,使用DAO對象訪問數據庫,就是中介者模式的一種體現,還有Spring IOC容器也是,將Bean的創建使用抽離出來統一管理。

還有,有時我們業務中,有種業務場景,沒有與之對應的實體(像User對應UserService、UserDAO),而是業務邏輯中產生的對象,如CheckService(檢查服務,根據日志表、用戶表,檢查用戶狀態是否正常),我們不直接在UserService里實現,而是抽出一個CheckService,這也是中介者模式的一種實現。

總結

本文介紹了行為型設計模式中的中介者模式,參考《設計模式就該這樣學》、《秒懂設計模式》兩書,通訊交友、聊天室場景是《秒懂設計模式》中的舉例。

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

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

相關文章

Oracle 的 SEC_CASE_SENSITIVE_LOGON 參數

Oracle 的SEC_CASE_SENSITIVE_LOGON 參數 關鍵版本信息 SEC_CASE_SENSITIVE_LOGON 參數在以下版本中被棄用&#xff1a; Oracle 12c Release 1 (12.1)&#xff1a; 該參數首次被標記為"過時"(obsolete)但依然保持功能有效 Oracle 18c/19c 及更高版本&#xff1a; …

《圖解技術體系》How Redis Architecture Evolves?

Redis架構的演進經歷了多個關鍵階段&#xff0c;從最初的內存數據庫發展為支持分布式、多模型和持久化的高性能系統。以下為具體演進路徑&#xff1a; 單線程模型與基礎數據結構 Redis最初采用單線程架構&#xff0c;利用高效的I/O多路復用&#xff08;如epoll&#xff09;處…

【電賽培訓課】測量與信號類賽題分析

一、賽題基本情況及硬件電路準備 &#xff08;一&#xff09;賽題基本情況 1.測量與信號類賽題統計 2.測量與信號類賽題特點 &#xff08;二&#xff09;硬件電路準備 綜測環節不允許帶入電腦和手機&#xff0c;需要自己根據題目要求和芯片參數指標進行設計和計算&#xff0c…

移動AI神器GPT Mobile:多模型自由切換

GPT Mobile是什么 GPT Mobile是一款開源的本地移動部署AI工具,主要用于安卓設備。以下是其相關介紹: 功能特點 多模型交互:支持與多個大型語言模型(LLM)同時進行對話,用戶導入相應的API密鑰,就可連接OpenAI、Anthropic、Google、Ollama等平臺,還能根據需求自由切換不同…

AirSim/Cosys-AirSim 游戲開發(二)使用自定義場景

在實際的開發過程中很少會只用 AirSim 自帶的 Blocks 場景&#xff0c;通常需要用到自定義的一些環境和模型&#xff0c;依托于強大的 UE 引擎可以較為逼真地完成場景渲染。這篇博客記錄了如何從頭開始導入一個自定義場景并加載 AirSim 插件。 【Note】&#xff1a;由于 UE Ed…

GPU 圖形計算綜述 (三):可編程管線 (Programmable Pipeline)

2000年左右&#xff0c;微軟在DirectX 8.0中首次提出了Shader Model 1.0和頂點著色器&#xff08;Vertex Shader&#xff09;的概念&#xff0c;標志著可編程管線時代的來臨。隨后&#xff0c;在DirectX 9.0中推出了Shader Model 2.0和像素著色器&#xff08;Pixel Shader&…

【Go語言基礎【3】】變量、常量、值類型與引用類型

文章目錄 一、值&#xff08;Value&#xff09;與字面量&#xff08;Literal&#xff09;1. 值2. 字面量 二、變量&#xff08;Variable&#xff09;1. 聲明方式2. 賦值方式3. 變量默認值4. 類型與值的匹配 三、常量&#xff08;Constant&#xff09;1. 聲明方式2. 常量的特性3…

AWS 亞馬遜 S3存儲桶直傳 前端demo 復制即可使用

自己踩過坑不想別人也踩坑了 亞馬遜S3存儲桶直傳前端demo復制即可使用 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0…

Python數據可視化科技圖表繪制系列教程(四)

目錄 帶基線的棒棒糖圖1 帶基線的棒棒糖圖2 帶標記的棒棒糖圖 啞鈴圖1 啞鈴圖2 包點圖1 包點圖2 雷達圖1 雷達圖2 交互式雷達圖 【聲明】&#xff1a;未經版權人書面許可&#xff0c;任何單位或個人不得以任何形式復制、發行、出租、改編、匯編、傳播、展示或利用本博…

如何有效刪除 iPhone 上的所有內容?

“在出售我的 iPhone 之前&#xff0c;我該如何清除它&#xff1f;我擔心如果我賣掉它&#xff0c;有人可能會從我的 iPhone 中恢復我的信息。” 升級到新 iPhone 后&#xff0c;你如何處理舊 iPhone&#xff1f;你打算出售、以舊換新還是捐贈&#xff1f;無論你選擇哪一款&am…

[yolov11改進系列]基于yolov11使用SwinTransformer替換backbone用于提高多尺度特征提取能力的python源碼+訓練源碼

【SwinTransformer介紹】 摘要 ViT的缺點&#xff1a; Transformer在語言處理中的基本元素是word token&#xff0c;其特點是語義信息比較密集。而ViT中token的尺度&#xff08;scale&#xff09;是固定的&#xff0c;且視覺token攜帶的語義信息比語言文字序列差&#xff0c…

NoSQL 之 Redis 配置與優化

目錄 一、Redis 介紹 1、關系型數據庫與非關系型數據庫 &#xff08;1&#xff09;關系型數據庫 &#xff08;2&#xff09;非關系型數據庫 &#xff08;3&#xff09;非關系型數據庫產生背景 2、Redis 基礎 &#xff08;1&#xff09;Redis 簡介 &#xff08;2&#x…

算法復雜度,咕咕咕

1.數據結構與算法 數據結構是計算機存儲&#xff0c;組織數據的方式&#xff0c;指相互之間存在一種或多種特定關系的數據元素的集合。可以理解為形狀不同的容器。 算法是定義好的計算過程&#xff0c;取輸入值&#xff0c;經過一系列計算方法變成輸出值。 &#xff08;推薦…

【Linux】 Linux 進程控制

參考博客&#xff1a;https://blog.csdn.net/sjsjnsjnn/article/details/125581083 一、進程創建 1.1 fork()函數 在linux中fork函數是非常重要的函數&#xff0c;它從已存在進程中創建一個新進程。新進程為子進程&#xff0c;而原進程為父進程。進程調用fork&#xff0c;當…

【大模型】MCP是啥?它和點菜、做菜、端菜有啥關系?

什么是 Model Context Protocol (MCP)? Model Context Protocol(模型上下文協議),通俗來說,就是一套用來管理、傳遞和維護對話或交互中上下文信息的規則和格式標準。 換句話說,MCP定義了模型在處理用戶輸入和生成回答時,如何理解、保留和傳遞上下文信息的協議,確保對…

機器學習的數學基礎:決策樹

決策樹 文章目錄 決策樹決策樹的基本思想劃分選擇信息增益增益率基尼指數 減枝處理回歸問題對連續值的處理對缺失值的處理 決策樹的基本思想 決策樹是基于樹結構來進行決策的&#xff0c;通過對問題的判斷與決策&#xff0c;得到最終決策。 一般的&#xff0c;決策樹包括一個…

基于若依前后分離版-用戶密碼錯誤鎖定

sys_config配置參數 user.password.maxRetryCount&#xff1a;最大錯誤次數 user.password.lockTime&#xff1a;鎖定時長 //SysLoginController//登錄 PostMapping("/login") public AjaxResult login(RequestBody LoginBody loginBody) {AjaxResult ajax AjaxR…

Java線程安全集合類

Java線程安全集合類全面解析 目錄 并發集合概述List線程安全實現Set線程安全實現Map線程安全實現Queue線程安全實現總結 并發集合概述 Java提供了多種線程安全的集合類&#xff0c;主要分為兩大類&#xff1a; 傳統同步集合&#xff1a;通過synchronized關鍵字實現線程安全…

匯川變頻器MD600S-4T-5R5為什么要搭配GRJ9000S-10-T濾波器?

一、變頻器的工作原理與電磁干擾 匯川MD600S-4T-5R5變頻器是一款緊湊型高性能變頻器&#xff0c;適用于三相380V-480V電網&#xff0c;額定電流5.5A&#xff0c;支持矢量控制和多種編碼器接口&#xff0c;適用于需要高精度速度和轉矩控制的場景&#xff0c;如機器人、電梯、紡…

數學運算在 OpenCV 中的核心作用與視覺效果演示

在計算機視覺中&#xff0c;圖像不僅僅是我們肉眼所見的內容&#xff0c;它其實是由數值矩陣組成的“數據”。而在 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;中&#xff0c;正是數學運算賦予了圖像處理無限的可能——從基本的濾波、增強到復雜的特征…