設計模式之中介模式(三分鐘學會一個設計模式)

来源:https://www.cnblogs.com/jilodream/p/18429808
-Advertisement-
Play Games

中介模式(Mediator)又稱之為調停模式。mediator [ˈmiːdieɪtə(r)] n. 調停者;斡旋者;解決紛爭的人(或機構); 本意就是解決糾紛的中間人它是面向對象六大原則中最少知道原則的一個典型應用。(關於面向對象六大原則,可看前文:https://www.cnblogs.com/ ...


中介模式(Mediator)又稱之為調停模式。
mediator [ˈmiːdieɪtə(r)]
n. 調停者;斡旋者;解決紛爭的人(或機構); 本意就是解決糾紛的中間人
它是面向對象六大原則中最少知道原則的一個典型應用。
(關於面向對象六大原則,可看前文:https://www.cnblogs.com/jilodream/p/5353512.html)
大概意思就是類設計時與外界儘量減低耦合,儘量少的依賴其他類,這樣就會降低類後期修改的風險。
官方的的定義如下:用一個中介對象來封裝一系列的對象交互。中介對象使得其他各個對象不再需要顯示的相互引用。使整體的耦合更加鬆散,而且可以改變獨立的改變他們之間的交互。

它是面向對象的23種設計模式中的一種,屬於行為模式的範圍。
中介模式大概就是這樣,比如你去買房,不論是價格討論,還是房子質量,都通過中介來進行,儘管中介會包裝一些邏輯,但是買家不需要管理所有賣家的信息,保留賣家的聯繫方式。賣家呢也不需要管理買家的信息,保留買家的聯繫方式。儘管是買賣房子,但是買家和賣家之間都是通過中介來進行交互,並不直接溝通。這樣做的好處就是買賣雙方都減輕了自己的工作負擔,不需要牢記對方的相關特性,所有這些都交給中介來維護。
比如沒有加入中介對象時,我們A/B 雙方大概需要維護m*n依賴條,如果雙方還要互相依賴,則是2*m*n條依賴,當A、B雙方的實例越來越多時,情況也會越來越複雜。
當我們加入中介對象時,則只需要維護A/B和中介對象之間的依賴,約2(m+n)條依賴,(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )

區別大概是下麵這個樣子

直接耦合

通過中介者組織

有些人會說AB 對象我就互相調用一下,需要搞這麼複雜麽?

如果只是簡單調用,當然沒必要引入中介類,當然是怎麼簡單怎麼來,但是倘若業務未來(或者已經)依賴很複雜,就應該儘早引入中介類,降低類之間不必要的耦合。

來看一個例子,調用雙方是
銀行和企業,他們可以互相給對方發消息。我們通過中介模式來組織整體結構:

銀行介面:

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 /**
 4  * @discription
 5  */
 6 public interface Bank {
 7     void sendMsg(String msg);
 8 
 9     void receiveMsg(String msg);
10 
11     void register(UnionPay unionPay);
12 }

工商銀行實現

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class ICBCBank implements Bank {
10 
11     private UnionPay unionPay;
12 
13     @Override
14     public void sendMsg(String msg) {
15         log.warn("工商銀行發送消息到企業:" + msg);
16         unionPay.sendCompany(msg);
17     }
18 
19     @Override
20     public void receiveMsg(String msg) {
21         log.warn("工商銀行收到企業消息:" + msg);
22     }
23 
24     @Override
25     public void register(UnionPay unionPay) {
26         this.unionPay = unionPay;
27     }
28 }

建設銀行實現

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class CCBBank implements Bank {
10 
11     private UnionPay unionPay;
12 
13     @Override
14     public void sendMsg(String msg) {
15         log.warn("建設銀行發送消息到企業:" + msg);
16         unionPay.sendCompany(msg);
17     }
18 
19     @Override
20     public void receiveMsg(String msg) {
21         log.warn("建設銀行收到企業消息:" + msg);
22     }
23 
24     @Override
25     public void register(UnionPay unionPay) {
26         this.unionPay = unionPay;
27     }
28 }

企業介面

1 package com.example.demo.learn.pattern.behavior.mediator;
2 
3 public interface Company {
4     void sendMsg(String msg);
5 
6     void receiveMsg(String msg);
7 
8     void register(UnionPay unionPay);
9 }

千度公司

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class QianDuCompany implements Company {
10     private UnionPay unionPay;
11 
12     @Override
13     public void sendMsg(String msg) {
14         log.warn("千度公司發送消息到銀行:" + msg);
15         unionPay.sendBank(msg);
16     }
17 
18     @Override
19     public void receiveMsg(String msg) {
20         log.warn("千度公司收到銀行消息:" + msg);
21     }
22 
23     @Override
24     public void register(UnionPay unionPay) {
25         this.unionPay = unionPay;
26     }
27 }

大米公司

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import lombok.extern.slf4j.Slf4j;
 4 
 5 /**
 6  * @discription
 7  */
 8 @Slf4j
 9 public class DaMiCompany implements Company {
10     private UnionPay unionPay;
11 
12     @Override
13     public void sendMsg(String msg) {
14         log.warn("大米公司發送消息到銀行:" + msg);
15         unionPay.sendBank(msg);
16     }
17 
18     @Override
19     public void receiveMsg(String msg) {
20         log.warn("大米公司收到銀行消息:" + msg);
21     }
22 
23     @Override
24     public void register(UnionPay unionPay) {
25         this.unionPay = unionPay;
26     }
27 }

中介類

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
 4 
 5 import java.util.List;
 6 
 7 /**
 8  * @discription
 9  */
10 public class UnionPay {
11     private List<Bank> bankList = Lists.newArrayList();
12 
13     private List<Company> companyList = Lists.newArrayList();
14 
15     public void register(Object... components) {
16         for (Object component : components) {
17             if (component instanceof Company) {
18                 Company company = (Company) component;
19                 companyList.add(company);
20                 company.register(this);
21             }
22             if (component instanceof Bank) {
23                 Bank bank = (Bank) component;
24                 bankList.add(bank);
25                 bank.register(this);
26             }
27         }
28     }
29 
30     public void sendBank(String msg) {
31         for (Bank bank : bankList) {
32             bank.receiveMsg(msg);
33         }
34     }
35 
36     public void sendCompany(String msg) {
37         for (Company company : companyList) {
38             company.receiveMsg(msg);
39         }
40     }
41 }

主類

 1 package com.example.demo.learn.pattern.behavior.mediator;
 2 
 3 /**
 4  * @discription
 5  */
 6 public class PatternMain {
 7     public static void main(String[] args) {
 8         Bank ccbBank = new CCBBank();
 9         Bank icbcBank = new ICBCBank();
10         Company qianDuCompany = new QianDuCompany();
11         Company daMiCompany = new DaMiCompany();
12         UnionPay unionPay = new UnionPay();
13         unionPay.register(ccbBank, icbcBank, qianDuCompany, daMiCompany);
14         ccbBank.sendMsg("歡迎各位企業來建設銀行貸款!");
15         icbcBank.sendMsg("歡迎各位企業來工行洽談合作!");
16         daMiCompany.sendMsg("哪家銀行目前有低息企業貸款?");
17         daMiCompany.sendMsg("哪家銀行目前有工資卡優惠活動?");
18     }
19 }

運行主類後,效果如下:

18:58:03.965 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建設銀行發送消息到企業:歡迎各位企業來建設銀行貸款!
18:58:03.969 [main] WARN com.example.demo.learn.pattern.behavior.mediator.QianDuCompany - 千度公司收到銀行消息:歡迎各位企業來建設銀行貸款!
18:58:03.969 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司收到銀行消息:歡迎各位企業來建設銀行貸款!
18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商銀行發送消息到企業:歡迎各位企業來工行洽談合作!
18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.QianDuCompany - 千度公司收到銀行消息:歡迎各位企業來工行洽談合作!
18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司收到銀行消息:歡迎各位企業來工行洽談合作!
18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司發送消息到銀行:哪家銀行目前有低息企業貸款?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建設銀行收到企業消息:哪家銀行目前有低息企業貸款?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商銀行收到企業消息:哪家銀行目前有低息企業貸款?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司發送消息到銀行:哪家銀行目前有工資卡優惠活動?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建設銀行收到企業消息:哪家銀行目前有工資卡優惠活動?
18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商銀行收到企業消息:哪家銀行目前有工資卡優惠活動?

代碼類圖如下:

我們可以從類圖發現,銀行和企業並沒有直接關聯,他們都是直接耦合中介類,所有的請求和響應都是和中介類進行交互(防盜連接:本文首發自http://www.cnblogs.com/jilodream/ )

中介模式的優點是解耦:我們可以直接將第三方提供類進行組織,而不需要修改他們的代碼。
缺點也很明顯,業務依賴邏輯全部抽離到了中介類中,中介類會過於臃腫。

如果你覺得寫的不錯,歡迎轉載和點贊。 轉載時請保留作者署名jilodream/王若伊_恩賜解脫(博客鏈接:http://www.cnblogs.com/jilodream/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • title: Nuxt Kit 實用工具的使用示例 date: 2024/9/25 updated: 2024/9/25 author: cmdragon excerpt: 摘要:本文介紹了Nuxt Kit工具在開發集成工具或插件時,如何訪問和修改Nuxt應用中使用的Vite或webpack配置,以 ...
  • 混淆指定js文件 fomartJs.bat @echo off REM 定義一個包含文件名的數組 set jsFiles=("polyfills.b4665eab.js" "manifest.b09f6bad.js" "index.f8bec5fb.js") REM 遍曆數組中的每個文件 for % ...
  • title: 使用 Nuxt Kit 的構建器 API 來擴展配置 date: 2024/9/24 updated: 2024/9/24 author: cmdragon excerpt: 摘要:本文詳細介紹瞭如何使用 Nuxt Kit 的構建器 API 來擴展和定製 Nuxt 3 項目的 webp ...
  • 前言 React在很早之前的版本中加了useId,用於生成唯一ID。在Vue3.5版本中,終於也有了期待已久的useId。這篇文章來帶你搞清楚useId有哪些應用場景,以及他是如何實現的。 關註公眾號:【前端歐陽】,給自己一個進階vue的機會 useId的作用 他的作用也是生成唯一ID,同一個Vue ...
  • 1. 基本信息 構建可擴展分散式系統:方法與實踐 [美]伊恩·戈頓(Ian Gorton)著 機械工業出版社,2024年5月出版 1.1. 讀薄率 書籍總字數188千字,筆記總字數49688字。 讀薄率49688÷188000≈26.4% 1.2. 讀厚方向 設計模式:可復用面向對象軟體的基礎 程式 ...
  • 軟體工程課程 班級鏈接 作業要求 作業鏈接 作業目標 需求分析和原型設計 學號 102201312 隊友 102201311張碩 使用墨刀構建原型,原型鏈接:請點擊我 客戶現實困擾 ​ 在大學里,一些有想法的學生希望通過發起或參與跨專業的項目(創業、學術)來提升自己的綜合能力,拓寬知識面和積累人脈。 ...
  • 1. 可擴展系統的基本要素 1.1. 分散式系統在本質上就是複雜的,你必須考慮多種故障模式,並設計應對所有可能發生的情況的處理方式 1.2. 大規模應用程式需要協調大量的硬體和軟體組件,共同實現低延遲和高吞吐量的能力 1.3. 面臨的挑戰是將所有活動部件組合成一個應用程式來運行,使其既能滿足需求又不 ...
  • 1. 流處理系統 1.1. 時間就是金錢 1.1.1. 從數據中提取有價值的知識和獲得洞見的速度越快,就能越快地響應系統所觀察的世界的變化 1.1.2. 信用卡欺詐檢測 1.1.3. 網路安全中異常網路流量的捕獲 1.1.4. 在支持GPS的駕駛應用程式中進行的實時路線規劃 1.1.5. 社交媒體網 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...