中介者模式聽名字就能想到也是一種爲了解決耦合度的設計模式,其實中介者模式在結構上與觀察者、命令模式十分相像;而應用目的又與結構模式「門面模式」有些類似。但區別於命令模式的是大多數中介者角色對於客戶程序是透明的。固然形成這種區別的緣由是因爲他們要達到的目的不一樣。 html
中介者模式是指用一箇中介對象來封裝一系列的對象交互。中介者使個對象不須要顯示的相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。簡單地說,將原來兩個直接引用或者依賴的對象拆開,在中間加入一個「中介」對象,使得兩頭的對象分別與「中介」對象引用或者依賴。設計模式
例以下面這個結構,若是每一個元素兩兩之間要產生聯繫,關係就會變得錯綜複雜。ide
可是加了中介者以後,相互之間就能夠解耦了。變成以下的關係結構。post
和二跟老紀都是朝廷大臣,可是互相看不順眼,在皇上面前和和睦氣,背地裏各自互相參對方。固然有時候皇上頒佈旨意時讓兩個大臣一塊兒合做去完成任務,他們也會相互合做的。和二跟老紀都想收拾對方,可是奈何雙方官職不相上下,因此當想收拾對方時就會經過皇上來實現,這個時候咱們就當皇上理解爲中介者(感受有點牽強,就這樣吧😂)。下面用代碼來實現這個過程。學習
官員抽象類測試
/** * 官員(大臣)抽象類 */ public abstract class Official { protected Monarch monarch; /** * 每一個官員必然要與君主有聯繫 * @param monarch */ public Official(Monarch monarch){ this.monarch = monarch; } /** * 在抽象官員類中添加與中介者取得聯繫的方法 * @param monarch */ public void setMonarch(Monarch monarch){ this.monarch = monarch; } }
君主抽象類this
/** * 君主抽象類 */ public abstract class Monarch { /** * 君主保持着和各個官員的聯繫 */ 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); } /** * 處理各個官員之間的互相參奏的摺子 * @param name * @param method */ public abstract void execute(String name,String method); }
老紀url
/** * 老紀 */ public class LaoJi extends Official{ /** * 每一個官員必然要與君主有聯繫 * * @param monarch */ public LaoJi(Monarch monarch) { super(monarch); } /** * 作好本職工做 */ public void self(){ System.out.println("啓奏皇上,臣老紀參與編寫的四庫全書已經完成。"); } /** * 參其餘官員或與其餘官員合做 */ public void out(){ System.out.println("啓奏皇上,臣老紀要參和二一本,秀女選拔工做到如今還沒完成,理應當革職查辦。"); super.monarch.execute("heEr","self"); } }
和二spa
/** * 和二 */ public class HeEr extends Official { /** * 每一個官員必然要與君主有聯繫 * * @param monarch */ public HeEr(Monarch monarch) { super(monarch); } /** * 作好本職工做 */ public void self(){ System.out.println("啓奏皇上,臣和二掌管的秀女選拔工做已經完成。"); } /** * 參其餘官員或與其餘官員合做 */ public void out(){ System.out.println("啓奏皇上,臣和二要參老紀一本,四庫全書到目前還沒編寫完成,理應問斬。"); super.monarch.execute("laoji","self"); } }
黃三(乾隆皇上)設計
/** * 黃三(皇上) */ public class HuangSan extends Monarch { /** * 處理各個官員之間的互相參奏的摺子 * * @param name * @param method */ @Override public void execute(String name, String method) { //作好本身分內的事情 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(); } } } }
測試類
public class Client { public static void main(String[] args) { //建立一個君主 Monarch monarch = new HuangSan(); //建立兩個官員 LaoJi laoJi = new LaoJi(monarch); HeEr heEr = new HeEr(monarch); //君主和兩個官員創建關係 monarch.addOfficial("laoji",laoJi); monarch.addOfficial("heEr",heEr); //有本奏上,無本退朝。 //laoJi.self(); laoJi.out(); System.out.println("---------------啓奏完畢"); //heEr.self(); heEr.out(); System.out.println("---------------啓奏完畢"); } }
運行結果
啓奏皇上,臣老紀要參和二一本,秀女選拔工做到如今還沒完成,理應當革職查辦。 啓奏皇上,臣和二掌管的秀女選拔工做已經完成。 ---------------啓奏完畢 啓奏皇上,臣和二要參老紀一本,四庫全書到目前還沒編寫完成,理應問斬。 啓奏皇上,臣老紀參與編寫的四庫全書已經完成。 ---------------啓奏完畢
上面的這個例子就是實現了中介者模式,皇上成了老紀跟和二的中介者。這樣使得兩位大臣也不用直接互懟了,除了幹好本身的本職工做還能夠督促其餘同事完成工做。
中介者模式的組成角色以下所示
抽象中介者(Mediator)角色:抽象中介者角色定義統一的接口,用於各同事角色之間的通訊。上面例子中君主類表明的就是這個角色。
具體中介者(ConcreteMediator)角色:具體中介者角色經過協調各同事角色,實現協做行爲,爲此它要指導並引用各個同事角色。上面例子中皇上表明的就是這個角色。
同事(Colleague)角色:每個同事角色都知道對應的具體中介者角色,並且與其餘的同事角色通訊的時候,必定要經過中介者角色協做。上面的例子中老紀跟和二就是表明的這個角色。
中介者模式將一個網狀的系統結構變成一個以中介者對象爲中心的星形結構,在這個星型結構中,使用中介者對象與其餘對象的一對多關係來取代原有對象之間的多對多關係。
一、中介者模式簡化了對象之間的交互,它用中介者和同事的一對多交互代替了原來同事之間的多對多交互,一對多關係更容易理解、維護擴展,將本來難以理解的網狀結構轉換成相對簡單的星型結構。
二、中介者模式可將各同事對象解耦。中介者有利於各同事之間的鬆耦合,咱們能夠獨立的改變和複用每個同事和中介者,增長新的中介者和新的同事類都比較方便,更好的符合「開閉原則」。
三、能夠減小子類生成,中介者將本來分佈於多個對象間的行爲集中在一塊兒,改變這些行爲只需生成新的中介者子類便可,這使得各個同事類可被重用,無須對同事類進行擴展。
在具體中介者類中包含了大量同事之間的交互細節,可能會致使具體中介者類很是複雜,使得系統難以維護。
一、系統中對象之間存在複雜的引用關係,系統結構混亂且難以理解。
二、 一個對象因爲引用了其餘不少對象而且直接和這些對象通訊,致使難以複用該對象。
三、想經過一箇中間類來封裝多個類中的行爲,而又不想生成太多的子類。能夠經過引入中介者類來實現,在中介者中定義對象交互的公共行爲,若是須要改變行爲則能夠增長新的具體中介者類。
想了解更多的設計模式請查看Java設計模式學習記錄-GoF設計模式概述。