介紹:
中介者模式屬于行為型模式。它的定義為:用一個中介對象來封裝一系列的對象交互。中介者使各對象不需要顯式地相互調(diào)用,從而使其耦合松散,而且可以獨立地改變他們之間的交互。
類圖:

Mediator(抽象中介者角色):定義一個接口用于各同事之間的通訊。
ConcreteMediator(具體中介者角色):它從具體的同事對象接受信息,向具體同事對象發(fā)出命令,負(fù)責(zé)協(xié)調(diào)同事之間的交互。
Colleague(抽象同事角色):通過中介者對象與其它同事類進(jìn)行交互,并定義所有相互影響的同事類的公共功能。
ConcreteColleagueA/B(具體同事角色):繼承于Colleague,每個具體同事類都知道本身在小范圍內(nèi)的行為,而不知道它在大范圍內(nèi)的目的。
用法:
當(dāng)對象之間的關(guān)系復(fù)雜且相互依賴時,為防止修改一個對象的行為同時涉及修改很多其它對象的行為,可使用中介者模式。
個人理解:
中介者模式的核心邏輯就是解耦對象‘多對多’的相互依賴關(guān)系。當(dāng)遇到一大堆混亂的對象呈現(xiàn)“網(wǎng)狀結(jié)構(gòu)”,利用通過中介者模式解耦對象之間的通訊。理解上就是下圖所示:

例子:
日常生活中,我們經(jīng)常會用社交工具(QQ、微信)進(jìn)行聊天。在這其中,群組聊天的設(shè)計正是中介者模式的例子,我們下面模擬一下:
設(shè)計思路:每個聊天用戶就相當(dāng)于同事類,聊天服務(wù)器就相當(dāng)于我們的中介者。整個流程是用戶向聊天服務(wù)器發(fā)送一條消息,服務(wù)器會將此消息發(fā)送給群組中的所有人。
設(shè)計多人聊天群組
1、創(chuàng)建抽象中介者角色
public abstract class ChatMediator {
public abstract void register(ChatClient client);
public abstract void notice(ChatClient client,String message);
}
定義一些接口用于同事類的通訊。在這里我們定義一個加入群聊的行為和向所有人發(fā)送通知的行為。
2、實現(xiàn)具體中介者角色
public class ChatServer extends ChatMediator {
private List<ChatClient> clientList = new ArrayList<>();
@Override
public void notice(ChatClient client, String message) {
for (ChatClient c : clientList) {
if (!client.equals(c)) {
c.receiveMessage(message);
}
}
}
@Override
public void register(ChatClient client) {
if (client != null && !clientList.contains(client)) {
clientList.add(client);
}
}
}
具體中介者負(fù)責(zé)協(xié)調(diào)同事類之間的交互,notice()方法向所群組中除了自己之外的用戶發(fā)送消息。
3、創(chuàng)建抽象同事類
public abstract class ChatClient {
protected ChatMediator mediator;
public ChatClient(ChatMediator mediator){
this.mediator = mediator;
}
public abstract void sendMessage(String message);
public abstract void receiveMessage(String message);
}
每個用戶都有一個發(fā)送消息的方法和接收消息的方法,而消息的傳遞則通過中介者對象mediator處理。
4、實現(xiàn)具體同事類
public class Andy extends ChatClient {
public Andy(ChatMediator mediator) {
super(mediator);
mediator.register(this);
}
@Override
public void sendMessage(String message) {
System.out.println();
System.out.println("安迪發(fā)送一條消息:" + message);
mediator.notice(this, message);
}
@Override
public void receiveMessage(String message) {
System.out.println("安迪收到一條消息:" + message);
}
}
具體同事類忽略Ben、Cat、David等等的用戶,實現(xiàn)相似!
對于每個具體同事類(用戶)而言,它并不需要知道這個群里面到底有多少人,只知道自己是負(fù)責(zé)發(fā)送和接收消息的。
5、測試與運行結(jié)果
public class Group {
public static void main(String[] args) {
//聊天服務(wù)器
ChatServer chatServer = new ChatServer();
//三個小伙伴
Andy andy = new Andy(chatServer);
Ben ben = new Ben(chatServer);
Cat cat = new Cat(chatServer);
System.out.println("=====群聊信息=====");
andy.sendMessage("今晚去看復(fù)仇者聯(lián)盟4吧!");
System.out.println("-----——分割線——-----");
ben.sendMessage("好啊好啊~我期待了很久!");
System.out.println("-----——分割線---——--");
cat.sendMessage("我來負(fù)責(zé)買票?。?!");
}
}
=====群聊信息=====
安迪發(fā)送一條消息:今晚去看復(fù)仇者聯(lián)盟4吧!
Ben哥收到一條消息:今晚去看復(fù)仇者聯(lián)盟4吧!
貓貓收到一條消息:今晚去看復(fù)仇者聯(lián)盟4吧!
-----——分割線——-----
Ben哥發(fā)送一條消息:好啊好啊~我期待了很久!
安迪收到一條消息:好啊好啊~我期待了很久!
貓貓收到一條消息:好啊好啊~我期待了很久!
-----——分割線---——--
貓貓發(fā)送一條消息:我來負(fù)責(zé)買票?。?!
安迪收到一條消息:我來負(fù)責(zé)買票?。。?Ben哥收到一條消息:我來負(fù)責(zé)買票?。?!
每個用戶直接調(diào)用sendMessage()的方法就可以完成通訊了,就算是一個100人的大群每個用戶也不用改動代碼~
總結(jié):
? 中介者模式大大的好處就是降低類的關(guān)系復(fù)雜度,使對象可以更好地維護(hù)和擴(kuò)展。將多對多的“網(wǎng)狀結(jié)構(gòu)”轉(zhuǎn)化成一對多的“星型結(jié)構(gòu)”,復(fù)雜的交互邏輯交給了中介者了。
? 這個模式就是迪米特原則的具體體現(xiàn)。復(fù)習(xí)一下迪米特原則:
迪米特原則(Law Of Demeter,LOD),也稱最少知識原則。定義一個對象應(yīng)該對其他對象有最少的了解。
意思是只與朋友通訊(關(guān)聯(lián)度很高的類)。每個類都會必然用到其它類的屬性和方法,這稱為耦合。設(shè)計類的時候要把功能拆分,盡可能使用一個第三者的朋友來進(jìn)行兩者間的通訊。
? 另外,新手寫代碼很容易出現(xiàn)一個類文件有上千行代碼,N個成員變量放在一起相互調(diào)用。所以也不用急于使用中介者模式優(yōu)化代碼,需要考慮整個設(shè)計上是不是存在不合理的地方。
感謝您的閱讀~
轉(zhuǎn)載請注明出處喔:http://www.itdecent.cn/p/feac0f5fd817
推薦閱讀
基礎(chǔ)篇:
設(shè)計模式前篇之——UML類圖必會知識點
設(shè)計模式前篇之——一起過一下面向?qū)ο蟮母拍?/a>
創(chuàng)建型模式:
簡易理解設(shè)計模式之:簡單工廠模式——來試試接入支付功能
簡易理解設(shè)計模式之:工廠方法模式——數(shù)據(jù)存儲例子
簡易理解設(shè)計模式之:抽象工廠模式——更換數(shù)據(jù)庫例子
簡易理解設(shè)計模式之:建造者模式——學(xué)習(xí)使用“鏈?zhǔn)秸{(diào)用”
簡易理解設(shè)計模式之:原型模式——深、淺拷貝的概念
簡易理解設(shè)計模式之:單例模式——單例模式的幾種常用寫法
結(jié)構(gòu)型模式:
簡易理解設(shè)計模式之:適配器模式——Android列表視圖控件設(shè)計方式
簡易理解設(shè)計模式之:橋接模式——穿衣服經(jīng)典案例2
簡易理解設(shè)計模式之:組合模式——實現(xiàn)View中的樹狀結(jié)構(gòu)
簡易理解設(shè)計模式之:裝飾模式——穿衣服經(jīng)典案例
簡易理解設(shè)計模式之:外觀模式——第三方SDK的幫助類
簡易理解設(shè)計模式之:享元模式——五子棋游戲例子
簡易理解設(shè)計模式之:代理模式——iOS視圖控件設(shè)計方式
行為型模式:
簡易理解設(shè)計模式之:策略模式——優(yōu)化一下支付功能
簡易理解設(shè)計模式之:模板方法模式——Android中的BaseActivity基類
簡易理解設(shè)計模式之:觀察者模式——監(jiān)聽與回調(diào)
簡易理解設(shè)計模式之:狀態(tài)模式——優(yōu)化登錄操作
簡易理解設(shè)計模式之:備忘錄模式——Word文檔的工作原理
簡易理解設(shè)計模式之:迭代器模式——遍歷對象的好幫手
簡易理解設(shè)計模式之:命令模式——實現(xiàn)命令的參數(shù)化配置
簡易理解設(shè)計模式之:責(zé)任鏈模式——OA中請假流程示例
簡易理解設(shè)計模式之:中介者模式——多人聊天室例子
簡易理解設(shè)計模式之:解釋器模式——語言和文法
簡易理解設(shè)計模式之:訪問者模式——員工考核例子