設(shè)計模式之中介模式(三分鐘學(xué)會一個設(shè)計模式)
中介模式(Mediator)又稱之為調(diào)停模式。
mediator [?mi?die?t?(r)]
n. 調(diào)停者;斡旋者;解決紛爭的人(或機(jī)構(gòu)); 本意就是解決糾紛的中間人
它是面向?qū)ο罅笤瓌t中最少知道原則的一個典型應(yīng)用。
(關(guān)于面向?qū)ο罅笤瓌t,可看前文:http://www.rzrgm.cn/jilodream/p/5353512.html)
大概意思就是類設(shè)計時與外界盡量減低耦合,盡量少的依賴其他類,這樣就會降低類后期修改的風(fēng)險。
官方的的定義如下:用一個中介對象來封裝一系列的對象交互。中介對象使得其他各個對象不再需要顯示的相互引用。使整體的耦合更加松散,而且可以改變獨(dú)立的改變他們之間的交互。
它是面向?qū)ο蟮?3種設(shè)計模式中的一種,屬于行為模式的范圍。
中介模式大概就是這樣,比如你去買房,不論是價格討論,還是房子質(zhì)量,都通過中介來進(jìn)行,盡管中介會包裝一些邏輯,但是買家不需要管理所有賣家的信息,保留賣家的聯(lián)系方式。賣家呢也不需要管理買家的信息,保留買家的聯(lián)系方式。盡管是買賣房子,但是買家和賣家之間都是通過中介來進(jìn)行交互,并不直接溝通。這樣做的好處就是買賣雙方都減輕了自己的工作負(fù)擔(dān),不需要牢記對方的相關(guān)特性,所有這些都交給中介來維護(hù)。
比如沒有加入中介對象時,我們A/B 雙方大概需要維護(hù)m*n依賴條,如果雙方還要互相依賴,則是2*m*n條依賴,當(dāng)A、B雙方的實(shí)例越來越多時,情況也會越來越復(fù)雜。
當(dāng)我們加入中介對象時,則只需要維護(hù)A/B和中介對象之間的依賴,約2(m+n)條依賴,(防盜連接:本文首發(fā)自http://www.rzrgm.cn/jilodream/ )
區(qū)別大概是下面這個樣子
直接耦合

通過中介者組織

有些人會說AB 對象我就互相調(diào)用一下,需要搞這么復(fù)雜么?
如果只是簡單調(diào)用,當(dāng)然沒必要引入中介類,當(dāng)然是怎么簡單怎么來,但是倘若業(yè)務(wù)未來(或者已經(jīng))依賴很復(fù)雜,就應(yīng)該盡早引入中介類,降低類之間不必要的耦合。
來看一個例子,調(diào)用雙方是
銀行和企業(yè),他們可以互相給對方發(fā)消息。我們通過中介模式來組織整體結(jié)構(gòu):
銀行接口:
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 }
工商銀行實(shí)現(xiàn)
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("工商銀行發(fā)送消息到企業(yè):" + msg); 16 unionPay.sendCompany(msg); 17 } 18 19 @Override 20 public void receiveMsg(String msg) { 21 log.warn("工商銀行收到企業(yè)消息:" + msg); 22 } 23 24 @Override 25 public void register(UnionPay unionPay) { 26 this.unionPay = unionPay; 27 } 28 }
建設(shè)銀行實(shí)現(xiàn)
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("建設(shè)銀行發(fā)送消息到企業(yè):" + msg); 16 unionPay.sendCompany(msg); 17 } 18 19 @Override 20 public void receiveMsg(String msg) { 21 log.warn("建設(shè)銀行收到企業(yè)消息:" + msg); 22 } 23 24 @Override 25 public void register(UnionPay unionPay) { 26 this.unionPay = unionPay; 27 } 28 }
企業(yè)接口
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("千度公司發(fā)送消息到銀行:" + 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("大米公司發(fā)送消息到銀行:" + 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("歡迎各位企業(yè)來建設(shè)銀行貸款!"); 15 icbcBank.sendMsg("歡迎各位企業(yè)來工行洽談合作!"); 16 daMiCompany.sendMsg("哪家銀行目前有低息企業(yè)貸款?"); 17 daMiCompany.sendMsg("哪家銀行目前有工資卡優(yōu)惠活動?"); 18 } 19 }
運(yùn)行主類后,效果如下:
18:58:03.965 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建設(shè)銀行發(fā)送消息到企業(yè):歡迎各位企業(yè)來建設(shè)銀行貸款! 18:58:03.969 [main] WARN com.example.demo.learn.pattern.behavior.mediator.QianDuCompany - 千度公司收到銀行消息:歡迎各位企業(yè)來建設(shè)銀行貸款! 18:58:03.969 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司收到銀行消息:歡迎各位企業(yè)來建設(shè)銀行貸款! 18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商銀行發(fā)送消息到企業(yè):歡迎各位企業(yè)來工行洽談合作! 18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.QianDuCompany - 千度公司收到銀行消息:歡迎各位企業(yè)來工行洽談合作! 18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司收到銀行消息:歡迎各位企業(yè)來工行洽談合作! 18:58:03.970 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司發(fā)送消息到銀行:哪家銀行目前有低息企業(yè)貸款? 18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建設(shè)銀行收到企業(yè)消息:哪家銀行目前有低息企業(yè)貸款? 18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商銀行收到企業(yè)消息:哪家銀行目前有低息企業(yè)貸款? 18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.DaMiCompany - 大米公司發(fā)送消息到銀行:哪家銀行目前有工資卡優(yōu)惠活動? 18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.CCBBank - 建設(shè)銀行收到企業(yè)消息:哪家銀行目前有工資卡優(yōu)惠活動? 18:58:03.971 [main] WARN com.example.demo.learn.pattern.behavior.mediator.ICBCBank - 工商銀行收到企業(yè)消息:哪家銀行目前有工資卡優(yōu)惠活動?
代碼類圖如下:

我們可以從類圖發(fā)現(xiàn),銀行和企業(yè)并沒有直接關(guān)聯(lián),他們都是直接耦合中介類,所有的請求和響應(yīng)都是和中介類進(jìn)行交互(防盜連接:本文首發(fā)自http://www.rzrgm.cn/jilodream/ )
中介模式的優(yōu)點(diǎn)是解耦:我們可以直接將第三方提供類進(jìn)行組織,而不需要修改他們的代碼。
缺點(diǎn)也很明顯,業(yè)務(wù)依賴邏輯全部抽離到了中介類中,中介類會過于臃腫。
如果你覺得寫的不錯,歡迎轉(zhuǎn)載和點(diǎn)贊。 轉(zhuǎn)載時請保留作者署名jilodream/王若伊_恩賜解脫(博客鏈接:http://www.rzrgm.cn/jilodream/

浙公網(wǎng)安備 33010602011771號