相關文章
設計模式(一)設計六大原則
設計模式(二)單例模式的七種寫法
設計模式(三)建造者模式
設計模式(四)簡單工廠模式
設計模式(五)觀察者模式
設計模式(六)代理模式
設計模式(七)裝飾模式
設計模式(八)外觀模式
設計模式(九)模版方法模式
設計模式(十)工廠方法模式
設計模式(十一)策略模式
設計模式(十二)享元模式
設計模式(十三)抽象工廠模式javascript
寫了不少篇設計模式的文章,才發現沒有講關於設計模式的分類,那麼這一篇就補上這一內容,順便帶來中介者模式的講解。並與此前講過的代理模式和外觀模式作對比。java
GoF提出的設計模式總共有23種,根據目的準則分類分爲三大類:git
另外隨着設計模式的發展也涌現出不少新的設計模式:它們分別是規格模式、對象池模式、僱工模式、黑板模式和空對象模式等。github
從前面講到的設計模式的分類中,咱們應該得知中介者模式是行爲型模式的一種,旨在處理類或對象如何交互及如何分配職責。
中介者模式又叫作調停者模式,名字跟出國留學中介和房產中介是相似的。拿房產中介來講,如今房子買家和房子賣家很是多,若是任由房子買家和房子賣家自由交易,則會致使不一樣的買家和賣家之間有不少交互,一個買家會和多個賣家進行交涉,一樣的一個賣家也會和多個買家進行交涉。若是在買房的過程當中出現糾紛問題,則很難進行解決。就以下圖所示同樣。設計模式
能夠看出房子買家和賣家進行了不少錯綜複雜的交互,而且買家A和賣家B,買家D和賣家D還產生了糾紛,一看到這個圖咱們就以爲的暈,固然比咱們暈的還有房子買家和賣家。咱們在 設計模式(一)設計六大原則這篇文章講過迪米特原則,這個原則所說的就是要儘可能減小對象之間的交互,若是兩個對象之間沒必要彼此直接通訊,那麼這兩個對象就不該當發生任何直接的相互做用,若是其中的一個對象須要調用另外一個對象的某一個方法的話,能夠經過第三者轉發這個調用。迪米特原則一樣適用於本場景,咱們能夠引入第三者也就是房產中介。它的出現不須要買家和賣家進行直接交涉,而是經過房產中介而進行交涉。而且也不容易出現買賣家之間糾紛,由於有中介者房產中介進行第三方監督。以下圖所示。
微信
圖中的關係清晰了不少。回到咱們軟件開發中,咱們爲了減小對象之間的交互和耦合,符合迪米特原則,那麼就可使用中介者模式,先來學習下中介者模式的定義。
中介者模式定義
定義:用一箇中介者對象來封裝一系列的對象交互。中介者使得各對象不須要顯式地相互引用,從而使其鬆散耦合,並且能夠獨立地改變它們之間的交互。ide
中介者模式結構圖以下圖所示。 學習
中介者模式簡單實現
中介者模式能夠拿武俠來舉例,江湖中門派衆多,門派以前由於想法不一樣會有不少的利益衝突,這樣就會帶來無休止的紛爭。爲了江湖的安寧,你們推舉出了一個你們都承認的武林盟主來對江湖紛爭進行調停。
前段時間武當派和峨眉派的的弟子被大力金剛指所殺,大力金剛指是少林派的絕學,由於事情重大,並且少林派實力強大,武當派和峨眉派不可以直接去少林派去問罪,只能上報武林盟主由武林盟主出面進行調停,以下圖所示。ui
抽象中介者角色
首先咱們建立抽象中介者類,在這個例子中,它是一個武林聯盟類,以下所示。this
public abstract class WulinAlliance {
public abstract void notice(String message, United united);
}複製代碼
notice方法用於向門派發送通知,其中United爲抽象同事類也就是門派類,接下來咱們來建立它。
抽象同事角色
public abstract class United {
protected WulinAlliance wulinAlliance;
public United(WulinAlliance wulinAlliance){
this.wulinAlliance=wulinAlliance;
}
}複製代碼
門派類(抽象同事類)會在構造方法中獲得武林聯盟類(抽象中介者類)。
具體同事角色
具體同事類包括武當派、峨眉派和少林派,以下所示。
/** * 具體同事類(武當) */
public class Wudang extends United {
public Wudang(WulinAlliance wulinAlliance) {
super(wulinAlliance);
}
public void sendAlliance(String message) {
wulinAlliance.notice(message, this);
}
public void getNotice(String message) {
System.out.println("武當收到消息:" + message);
}
}
/** * 具體同事類(峨眉派) */
public class Emei extends United {
public Emei(WulinAlliance wulinAlliance) {
super(wulinAlliance);
}
public void sendAlliance(String message) {
wulinAlliance.notice(message, Emei.this);
}
public void getNotice(String message) {
System.out.println("峨眉收到消息:" + message);
}
}
/** * 具體同事類(少林派) */
public class Shaolin extends United {
public Shaolin(WulinAlliance wulinAlliance) {
super(wulinAlliance);
}
public void sendAlliance(String message){
wulinAlliance.notice(message,Shaolin.this);
}
public void getNotice(String message){
System.out.println("少林收到消息:"+message);
}
}複製代碼
武當、峨眉和少林類都有兩個方法,其中getNotice方法是自有方法,對於其餘的門派(同事類)和武林聯盟(中介者)沒有依賴,只是用來接收武林盟主的通知。sendAlliance方法則是依賴方法,它必須經過武林盟主才能完成行爲。
具體中介者角色
具體中介者類則是武林盟主類,以下所示
public class Champions extends WulinAlliance {
private Wudang wudang;
private Shaolin shaolin;
private Emei emei;
public void setWudang(Wudang wudang) {
this.wudang = wudang;
}
public void setEmei(Emei emei) {
this.emei = emei;
}
public void setShaolin(Shaolin shaolin) {
this.shaolin = shaolin;
}
@Override
public void notice(String message, United united) {
if (united == wudang) {
shaolin.getNotice(message);
} else if (united == emei) {
shaolin.getNotice(message);
} else if (united == shaolin) {
wudang.getNotice(message);
emei.getNotice(message);
}
}
}複製代碼
武林盟主須要瞭解全部的門派,因此須要用setter來持有武當、峨眉和少林的引用。notice方法會根據不一樣門派發來的消息,轉而通知給其餘的門派。好比武當發來的消息,武林盟主就會將消息通知給少林。
客戶端調用
public class Client {
public static void main(String[]args) {
Champions champions=new Champions();
Wudang wudang=new Wudang(champions);
Shaolin shaolin=new Shaolin(champions);
Emei emei=new Emei(champions);
champions.setWudang(wudang);
champions.setShaolin(shaolin);
champions.setEmei(emei);
wudang.sendAlliance("武當弟子被少林大力金剛指所殺");
emei.sendAlliance("峨眉弟子被少林大力金剛指所殺");
shaolin.sendAlliance("少林弟子毫不會作出這種事情");
}
}複製代碼
首先建立武林盟主類Champions 並傳入到各個門派類,接着調用武林盟主類的setter方法傳入各個門派類,最後調用各個門派的sendAlliance方法經過武林盟主類向其餘門派發送消息。
輸出結果爲:
少林收到消息:武當弟子被少林大力金剛指所殺
少林收到消息:峨眉弟子被少林大力金剛指所殺
武當收到消息:少林弟子毫不會作出這種事情
峨眉收到消息:少林弟子毫不會作出這種事情
接下來給出這個例子的UML圖,以下所示。
中介者模式的優缺點和使用場景
優勢
符合迪米特原則,將原有的一對多的依賴變成了一對一的依賴,下降類間的耦合。
缺點
中介者會變得龐大且複雜,本來多個對象直接的相互依賴變成了中介者和多個同事類的依賴關係,同事類越多,中介者的邏輯就越複雜。
使用場景
中介者模式很容易實現呢,可是也容易誤用,不要着急使用,先要思考你的設計是否合理。
當對象之間的交互變多時,爲了防止一個類會涉及修改其餘類的行爲,可使用中介者模式,將系統從網狀結構變爲以中介者爲中心的星型結構。
當咱們學完中介者模式是否是會以爲和此前講過的代理模式和外觀模式有些相似呢?如今咱們一一來將它們進行對比。
代理模式和中介者模式
代理模式是結構型設計模式,它有不少種類型,主要是在訪問對象時引入必定程度的間接性,因爲有間接性,就能夠附加多種的用途,好比進行權限控制。中介者模式則是爲了減小對象之間的相互耦合。雖然網上有不少代理模式和中介者模式的對比,可是在我看來這二者實際上並無可比性,只是看起來有些相似罷了。
外觀模式和中介者模式
外觀模式主要是以封裝和隔離爲主要任務,中介者則是調停同事類之間的關係,所以,中介者具備部分業務的邏輯控制。他們之間的主要區別爲:
參考資料
《大話設計模式》
《設計模式之禪》
《Android源碼設計模式》
歡迎關注個人微信公衆號,第一時間得到博客更新提醒,以及更多成體系的Android相關原創技術乾貨。
掃一掃下方二維碼或者長按識別二維碼,便可關注。