Java設(shè)計(jì)模式學(xué)習(xí)記錄-中介者模式
前言
中介者模式聽名字就能想到也是一種為了解決耦合度的設(shè)計(jì)模式,其實(shí)中介者模式在結(jié)構(gòu)上與觀察者、命令模式十分相像;而應(yīng)用目的又與結(jié)構(gòu)模式“門面模式”有些相似。但區(qū)別于命令模式的是大多數(shù)中介者角色對(duì)于客戶程序是透明的。當(dāng)然造成這種區(qū)別的原因是由于他們要達(dá)到的目的不同。
中介者模式
概念介紹
中介者模式是指用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互。中介者使個(gè)對(duì)象不需要顯示的相互引用,從而使其耦合松散,而且可以獨(dú)立地改變它們之間的交互。簡(jiǎn)單地說,將原來兩個(gè)直接引用或者依賴的對(duì)象拆開,在中間加入一個(gè)“中介”對(duì)象,使得兩頭的對(duì)象分別與“中介”對(duì)象引用或者依賴。
例如下面這個(gè)結(jié)構(gòu),如果每個(gè)元素兩兩之間要產(chǎn)生聯(lián)系,關(guān)系就會(huì)變得錯(cuò)綜復(fù)雜。

但是加了中介者之后,相互之間就可以解耦了。變成如下的關(guān)系結(jié)構(gòu)。

舉例
和二跟老紀(jì)都是朝廷大臣,但是互相看不順眼,在皇上面前和和氣氣,背地里各自互相參對(duì)方。當(dāng)然有時(shí)候皇上頒布旨意時(shí)讓兩個(gè)大臣一起合作去完成任務(wù),他們也會(huì)相互合作的。和二跟老紀(jì)都想收拾對(duì)方,但是奈何雙方官職不相上下,所以當(dāng)想收拾對(duì)方時(shí)就會(huì)通過皇上來實(shí)現(xiàn),這個(gè)時(shí)候我們就當(dāng)皇上理解為中介者(感覺有點(diǎn)牽強(qiáng),就這樣吧??)。下面用代碼來實(shí)現(xiàn)這個(gè)過程。
官員抽象類
/** * 官員(大臣)抽象類 */ public abstract class Official { protected Monarch monarch; /** * 每個(gè)官員必然要與君主有聯(lián)系 * @param monarch */ public Official(Monarch monarch){ this.monarch = monarch; } /** * 在抽象官員類中添加與中介者取得聯(lián)系的方法 * @param monarch */ public void setMonarch(Monarch monarch){ this.monarch = monarch; } }
君主抽象類
/** * 君主抽象類 */ public abstract class Monarch { /** * 君主保持著和各個(gè)官員的聯(lián)系 */ protected ConcurrentHashMap<String,Official> officials = new ConcurrentHashMap<>(); /** * 錄用官員 * @param name * @param official */ public void addOfficial(String name,Official official){ this.officials.put(name,official); } /** * 將官員革職查辦 * @param name */ public void removeOfficial(String name){ this.officials.remove(name); } /** * 處理各個(gè)官員之間的互相參奏的折子 * @param name * @param method */ public abstract void execute(String name,String method); }
老紀(jì)
/** * 老紀(jì) */ public class LaoJi extends Official{ /** * 每個(gè)官員必然要與君主有聯(lián)系 * * @param monarch */ public LaoJi(Monarch monarch) { super(monarch); } /** * 做好本職工作 */ public void self(){ System.out.println("啟奏皇上,臣老紀(jì)參與編寫的四庫全書已經(jīng)完成。"); } /** * 參其他官員或與其他官員合作 */ public void out(){ System.out.println("啟奏皇上,臣老紀(jì)要參和二一本,秀女選拔工作到現(xiàn)在還沒完成,理應(yīng)當(dāng)革職查辦。"); super.monarch.execute("heEr","self"); } }
和二
/** * 和二 */ public class HeEr extends Official { /** * 每個(gè)官員必然要與君主有聯(lián)系 * * @param monarch */ public HeEr(Monarch monarch) { super(monarch); } /** * 做好本職工作 */ public void self(){ System.out.println("啟奏皇上,臣和二掌管的秀女選拔工作已經(jīng)完成。"); } /** * 參其他官員或與其他官員合作 */ public void out(){ System.out.println("啟奏皇上,臣和二要參老紀(jì)一本,四庫全書到目前還沒編寫完成,理應(yīng)問斬。"); super.monarch.execute("laoji","self"); } }
黃三(乾隆皇上)
/** * 黃三(皇上) */ public class HuangSan extends Monarch { /** * 處理各個(gè)官員之間的互相參奏的折子 * * @param name * @param method */ @Override public void execute(String name, String method) { //做好自己份內(nèi)的事情 if("self".equals(method)){ if("laoji".equals(name)){ ((LaoJi)super.officials.get(name)).self(); }else { ((HeEr)super.officials.get(name)).self(); } //我要參別人一本 }else { if("laoji".equals(name)){ ((LaoJi)super.officials.get(name)).out(); }else { ((LaoJi)super.officials.get(name)).out(); } } } }
測(cè)試類
public class Client { public static void main(String[] args) { //創(chuàng)建一個(gè)君主 Monarch monarch = new HuangSan(); //創(chuàng)建兩個(gè)官員 LaoJi laoJi = new LaoJi(monarch); HeEr heEr = new HeEr(monarch); //君主和兩個(gè)官員建立關(guān)系 monarch.addOfficial("laoji",laoJi); monarch.addOfficial("heEr",heEr); //有本奏上,無本退朝。 //laoJi.self(); laoJi.out(); System.out.println("---------------啟奏完畢"); //heEr.self(); heEr.out(); System.out.println("---------------啟奏完畢"); } }
運(yùn)行結(jié)果
啟奏皇上,臣老紀(jì)要參和二一本,秀女選拔工作到現(xiàn)在還沒完成,理應(yīng)當(dāng)革職查辦。 啟奏皇上,臣和二掌管的秀女選拔工作已經(jīng)完成。 ---------------啟奏完畢 啟奏皇上,臣和二要參老紀(jì)一本,四庫全書到目前還沒編寫完成,理應(yīng)問斬。 啟奏皇上,臣老紀(jì)參與編寫的四庫全書已經(jīng)完成。 ---------------啟奏完畢
上面的這個(gè)例子就是實(shí)現(xiàn)了中介者模式,皇上成了老紀(jì)跟和二的中介者。這樣使得兩位大臣也不用直接互懟了,除了干好自己的本職工作還可以督促其他同事完成工作。
迭代器模式的結(jié)構(gòu)

中介者模式的組成角色如下所示
抽象中介者(Mediator)角色:抽象中介者角色定義統(tǒng)一的接口,用于各同事角色之間的通信。上面例子中君主類代表的就是這個(gè)角色。
具體中介者(ConcreteMediator)角色:具體中介者角色通過協(xié)調(diào)各同事角色,實(shí)現(xiàn)協(xié)作行為,為此它要指導(dǎo)并引用各個(gè)同事角色。上面例子中皇上代表的就是這個(gè)角色。
同事(Colleague)角色:每一個(gè)同事角色都知道對(duì)應(yīng)的具體中介者角色,而且與其他的同事角色通信的時(shí)候,一定要通過中介者角色協(xié)作。上面的例子中老紀(jì)跟和二就是代表的這個(gè)角色。
總結(jié)
中介者模式將一個(gè)網(wǎng)狀的系統(tǒng)結(jié)構(gòu)變成一個(gè)以中介者對(duì)象為中心的星形結(jié)構(gòu),在這個(gè)星型結(jié)構(gòu)中,使用中介者對(duì)象與其他對(duì)象的一對(duì)多關(guān)系來取代原有對(duì)象之間的多對(duì)多關(guān)系。
優(yōu)點(diǎn)
1、中介者模式簡(jiǎn)化了對(duì)象之間的交互,它用中介者和同事的一對(duì)多交互代替了原來同事之間的多對(duì)多交互,一對(duì)多關(guān)系更容易理解、維護(hù)擴(kuò)展,將原本難以理解的網(wǎng)狀結(jié)構(gòu)轉(zhuǎn)換成相對(duì)簡(jiǎn)單的星型結(jié)構(gòu)。
2、中介者模式可將各同事對(duì)象解耦。中介者有利于各同事之間的松耦合,我們可以獨(dú)立的改變和復(fù)用每一個(gè)同事和中介者,增加新的中介者和新的同事類都比較方便,更好的符合“開閉原則”。
3、可以減少子類生成,中介者將原本分布于多個(gè)對(duì)象間的行為集中在一起,改變這些行為只需生成新的中介者子類即可,這使得各個(gè)同事類可被重用,無須對(duì)同事類進(jìn)行擴(kuò)展。
缺點(diǎn)
在具體中介者類中包含了大量同事之間的交互細(xì)節(jié),可能會(huì)導(dǎo)致具體中介者類非常復(fù)雜,使得系統(tǒng)難以維護(hù)。
適用場(chǎng)景
1、系統(tǒng)中對(duì)象之間存在復(fù)雜的引用關(guān)系,系統(tǒng)結(jié)構(gòu)混亂且難以理解。
2、 一個(gè)對(duì)象由于引用了其他很多對(duì)象并且直接和這些對(duì)象通信,導(dǎo)致難以復(fù)用該對(duì)象。
3、想通過一個(gè)中間類來封裝多個(gè)類中的行為,而又不想生成太多的子類。可以通過引入中介者類來實(shí)現(xiàn),在中介者中定義對(duì)象交互的公共行為,如果需要改變行為則可以增加新的具體中介者類。
想了解更多的設(shè)計(jì)模式請(qǐng)查看Java設(shè)計(jì)模式學(xué)習(xí)記錄-GoF設(shè)計(jì)模式概述。
作者:紀(jì)莫
歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處。
限于本人水平,如果文章和代碼有表述不當(dāng)之處,還請(qǐng)不吝賜教。
歡迎掃描二維碼關(guān)注公眾號(hào):Jimoer
文章會(huì)同步到公眾號(hào)上面,大家一起成長(zhǎng),共同提升技術(shù)能力。
聲援博主:如果您覺得文章對(duì)您有幫助,可以點(diǎn)擊文章右下角【推薦】一下。
您的鼓勵(lì)是博主的最大動(dòng)力!


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