# 協調多個對象之間的交互——中介者模式(二)
20.2 中介者模式概述
如果在一個系統中對象之間的聯系呈現為網狀結構,如圖20-4所示。對象之間存在大量的多對多聯系,將導致系統非常復雜,這些對象既會影響別的對象,也會被別的對象所影響,這些對象稱為同事對象,它們之間通過彼此的相互作用實現系統的行為。在網狀結構中,幾乎每個對象都需要與其他對象發生相互作用,而這種相互作用表現為一個對象與另外一個對象的直接耦合,這將導致一個過度耦合的系統。

圖20-4 對象之間存在復雜關系的網狀結構
中介者模式可以使對象之間的關系數量急劇減少,通過引入中介者對象,可以將系統的網狀結構變成以中介者為中心的星形結構,如圖20-5所示。在這個星形結構中,同事對象不再直接與另一個對象聯系,它通過中介者對象與另一個對象發生相互作用。中介者對象的存在保證了對象結構上的穩定,也就是說,系統的結構不會因為新對象的引入帶來大量的修改工作。

圖20-5 引入中介者對象的星型結構
如果在一個系統中對象之間存在多對多的相互關系,我們可以將對象之間的一些交互行為從各個對象中分離出來,并集中封裝在一個中介者對象中,并由該中介者進行統一協調,這樣對象之間多對多的復雜關系就轉化為相對簡單的一對多關系。通過引入中介者來簡化對象之間的復雜交互,中介者模式是“迪米特法則”的一個典型應用。
中介者模式定義如下:
> 中介者模式(Mediator Pattern):用一個中介對象(中介者)來封裝一系列的對象交互,中介者使各對象不需要顯式地相互引用,從而使其耦合松散,而且可以獨立地改變它們之間的交互。中介者模式又稱為調停者模式,它是一種對象行為型模式。
在中介者模式中,我們引入了用于協調其他對象/類之間相互調用的中介者類,為了讓系統具有更好的靈活性和可擴展性,通常還提供了抽象中介者,其結構圖如圖20-6所示:

圖20-6 中介者模式結構圖
在中介者模式結構圖中包含如下幾個角色:
● Mediator(抽象中介者):它定義一個接口,該接口用于與各同事對象之間進行通信。
● ConcreteMediator(具體中介者):它是抽象中介者的子類,通過協調各個同事對象來實現協作行為,它維持了對各個同事對象的引用。
● Colleague(抽象同事類):它定義各個同事類公有的方法,并聲明了一些抽象方法來供子類實現,同時它維持了一個對抽象中介者類的引用,其子類可以通過該引用來與中介者通信。
● ConcreteColleague(具體同事類):它是抽象同事類的子類;每一個同事對象在需要和其他同事對象通信時,先與中介者通信,通過中介者來間接完成與其他同事類的通信;在具體同事類中實現了在抽象同事類中聲明的抽象方法。
中介者模式的核心在于中介者類的引入,在中介者模式中,中介者類承擔了兩方面的職責:
(1) 中轉作用(結構性):通過中介者提供的中轉作用,各個同事對象就不再需要顯式引用其他同事,當需要和其他同事進行通信時,可通過中介者來實現間接調用。該中轉作用屬于中介者在結構上的支持。
(2) 協調作用(行為性):中介者可以更進一步的對同事之間的關系進行封裝,同事可以一致的和中介者進行交互,而不需要指明中介者需要具體怎么做,中介者根據封裝在自身內部的協調邏輯,對同事的請求進行進一步處理,將同事成員之間的關系行為進行分離和封裝。該協調作用屬于中介者在行為上的支持。
在中介者模式中,典型的抽象中介者類代碼如下所示:
```
abstract class Mediator {
protected ArrayList<Colleague> colleagues; //用于存儲同事對象
//注冊方法,用于增加同事對象
public void register(Colleague colleague) {
colleagues.add(colleague);
}
//聲明抽象的業務方法
public abstract void operation();
}
在抽象中介者中可以定義一個同事類的集合,用于存儲同事對象并提供注冊方法,同時聲明了具體中介者類所具有的方法。在具體中介者類中將實現這些抽象方法,典型的具體中介者類代碼如下所示:
[java] view plain copy
class ConcreteMediator extends Mediator {
//實現業務方法,封裝同事之間的調用
public void operation() {
......
((Colleague)(colleagues.get(0))).method1(); //通過中介者調用同事類的方法
......
}
}
```
在具體中介者類中將調用同事類的方法,調用時可以增加一些自己的業務代碼對調用進行控制。
在抽象同事類中維持了一個抽象中介者的引用,用于調用中介者的方法,典型的抽象同事類代碼如下所示:
```
abstract class Colleague {
protected Mediator mediator; //維持一個抽象中介者的引用
public Colleague(Mediator mediator) {
this.mediator=mediator;
}
public abstract void method1(); //聲明自身方法,處理自己的行為
//定義依賴方法,與中介者進行通信
public void method2() {
mediator.operation();
}
}
```
在抽象同事類中聲明了同事類的抽象方法,而在具體同事類中將實現這些方法,典型的具體同事類代碼如下所示:
```
class ConcreteColleague extends Colleague {
public ConcreteColleague(Mediator mediator) {
super(mediator);
}
//實現自身方法
public void method1() {
......
}
}
```
在具體同事類ConcreteColleague中實現了在抽象同事類中聲明的方法,其中方法method1()是同事類的自身方法(Self-Method),用于處理自己的行為,而方法method2()是依賴方法(Depend-Method),用于調用在中介者中定義的方法,依賴中介者來完成相應的行為,例如調用另一個同事類的相關方法。
思考
如何理解同事類中的自身方法與依賴方法?
- Introduction
- 基礎知識
- 設計模式概述
- 從招式與內功談起——設計模式概述(一)
- 從招式與內功談起——設計模式概述(二)
- 從招式與內功談起——設計模式概述(三)
- 面向對象設計原則
- 面向對象設計原則之單一職責原則
- 面向對象設計原則之開閉原則
- 面向對象設計原則之里氏代換原則
- 面向對象設計原則之依賴倒轉原則
- 面向對象設計原則之接口隔離原則
- 面向對象設計原則之合成復用原則
- 面向對象設計原則之迪米特法則
- 六個創建型模式
- 簡單工廠模式-Simple Factory Pattern
- 工廠三兄弟之簡單工廠模式(一)
- 工廠三兄弟之簡單工廠模式(二)
- 工廠三兄弟之簡單工廠模式(三)
- 工廠三兄弟之簡單工廠模式(四)
- 工廠方法模式-Factory Method Pattern
- 工廠三兄弟之工廠方法模式(一)
- 工廠三兄弟之工廠方法模式(二)
- 工廠三兄弟之工廠方法模式(三)
- 工廠三兄弟之工廠方法模式(四)
- 抽象工廠模式-Abstract Factory Pattern
- 工廠三兄弟之抽象工廠模式(一)
- 工廠三兄弟之抽象工廠模式(二)
- 工廠三兄弟之抽象工廠模式(三)
- 工廠三兄弟之抽象工廠模式(四)
- 工廠三兄弟之抽象工廠模式(五)
- 單例模式-Singleton Pattern
- 確保對象的唯一性——單例模式 (一)
- 確保對象的唯一性——單例模式 (二)
- 確保對象的唯一性——單例模式 (三)
- 確保對象的唯一性——單例模式 (四)
- 確保對象的唯一性——單例模式 (五)
- 原型模式-Prototype Pattern
- 對象的克隆——原型模式(一)
- 對象的克隆——原型模式(二)
- 對象的克隆——原型模式(三)
- 對象的克隆——原型模式(四)
- 建造者模式-Builder Pattern
- 復雜對象的組裝與創建——建造者模式(一)
- 復雜對象的組裝與創建——建造者模式(二)
- 復雜對象的組裝與創建——建造者模式(三)
- 七個結構型模式
- 適配器模式-Adapter Pattern
- 不兼容結構的協調——適配器模式(一)
- 不兼容結構的協調——適配器模式(二)
- 不兼容結構的協調——適配器模式(三)
- 不兼容結構的協調——適配器模式(四)
- 橋接模式-Bridge Pattern
- 處理多維度變化——橋接模式(一)
- 處理多維度變化——橋接模式(二)
- 處理多維度變化——橋接模式(三)
- 處理多維度變化——橋接模式(四)
- 組合模式-Composite Pattern
- 樹形結構的處理——組合模式(一)
- 樹形結構的處理——組合模式(二)
- 樹形結構的處理——組合模式(三)
- 樹形結構的處理——組合模式(四)
- 樹形結構的處理——組合模式(五)
- 裝飾模式-Decorator Pattern
- 擴展系統功能——裝飾模式(一)
- 擴展系統功能——裝飾模式(二)
- 擴展系統功能——裝飾模式(三)
- 擴展系統功能——裝飾模式(四)
- 外觀模式-Facade Pattern
- 深入淺出外觀模式(一)
- 深入淺出外觀模式(二)
- 深入淺出外觀模式(三)
- 享元模式-Flyweight Pattern
- 實現對象的復用——享元模式(一)
- 實現對象的復用——享元模式(二)
- 實現對象的復用——享元模式(三)
- 實現對象的復用——享元模式(四)
- 實現對象的復用——享元模式(五)
- 代理模式-Proxy Pattern
- 設計模式之代理模式(一)
- 設計模式之代理模式(二)
- 設計模式之代理模式(三)
- 設計模式之代理模式(四)
- 十一個行為型模式
- 職責鏈模式-Chain of Responsibility Pattern
- 請求的鏈式處理——職責鏈模式(一)
- 請求的鏈式處理——職責鏈模式(二)
- 請求的鏈式處理——職責鏈模式(三)
- 請求的鏈式處理——職責鏈模式(四)
- 命令模式-Command Pattern
- 請求發送者與接收者解耦——命令模式(一)
- 請求發送者與接收者解耦——命令模式(二)
- 請求發送者與接收者解耦——命令模式(三)
- 請求發送者與接收者解耦——命令模式(四)
- 請求發送者與接收者解耦——命令模式(五)
- 請求發送者與接收者解耦——命令模式(六)
- 解釋器模式-Interpreter Pattern
- 自定義語言的實現——解釋器模式(一)
- 自定義語言的實現——解釋器模式(二)
- 自定義語言的實現——解釋器模式(三)
- 自定義語言的實現——解釋器模式(四)
- 自定義語言的實現——解釋器模式(五)
- 自定義語言的實現——解釋器模式(六)
- 迭代器模式-Iterator Pattern
- 遍歷聚合對象中的元素——迭代器模式(一)
- 遍歷聚合對象中的元素——迭代器模式(二)
- 遍歷聚合對象中的元素——迭代器模式(三)
- 遍歷聚合對象中的元素——迭代器模式(四)
- 遍歷聚合對象中的元素——迭代器模式(五)
- 遍歷聚合對象中的元素——迭代器模式(六)
- 中介者模式-Mediator Pattern
- 協調多個對象之間的交互——中介者模式(一)
- 協調多個對象之間的交互——中介者模式(二)
- 協調多個對象之間的交互——中介者模式(三)
- 協調多個對象之間的交互——中介者模式(四)
- 協調多個對象之間的交互——中介者模式(五)
- 備忘錄模式-Memento Pattern
- 撤銷功能的實現——備忘錄模式(一)
- 撤銷功能的實現——備忘錄模式(二)
- 撤銷功能的實現——備忘錄模式(三)
- 撤銷功能的實現——備忘錄模式(四)
- 撤銷功能的實現——備忘錄模式(五)
- 觀察者模式-Observer Pattern
- 對象間的聯動——觀察者模式(一)
- 對象間的聯動——觀察者模式(二)
- 對象間的聯動——觀察者模式(三)
- 對象間的聯動——觀察者模式(四)
- 對象間的聯動——觀察者模式(五)
- 對象間的聯動——觀察者模式(六)
- 狀態模式-State Pattern
- 處理對象的多種狀態及其相互轉換——狀態模式(一)
- 處理對象的多種狀態及其相互轉換——狀態模式(二)
- 處理對象的多種狀態及其相互轉換——狀態模式(三)
- 處理對象的多種狀態及其相互轉換——狀態模式(四)
- 處理對象的多種狀態及其相互轉換——狀態模式(五)
- 處理對象的多種狀態及其相互轉換——狀態模式(六)
- 策略模式-Strategy Pattern
- 算法的封裝與切換——策略模式(一)
- 算法的封裝與切換——策略模式(二)
- 算法的封裝與切換——策略模式(三)
- 算法的封裝與切換——策略模式(四)
- 模板方法模式-Template Method Pattern
- 模板方法模式深度解析(一)
- 模板方法模式深度解析(二)
- 模板方法模式深度解析(三)
- 訪問者模式-Visitor Pattern
- 操作復雜對象結構——訪問者模式(一)
- 操作復雜對象結構——訪問者模式(二)
- 操作復雜對象結構——訪問者模式(三)
- 操作復雜對象結構——訪問者模式(四)
- 設計模式趣味學習(復習)
- 設計模式與足球(一)
- 設計模式與足球(二)
- 設計模式與足球(三)
- 設計模式與足球(四)
- 設計模式綜合應用實例
- 多人聯機射擊游戲
- 多人聯機射擊游戲中的設計模式應用(一)
- 多人聯機射擊游戲中的設計模式應用(二)
- 數據庫同步系統
- 設計模式綜合實例分析之數據庫同步系統(一)
- 設計模式綜合實例分析之數據庫同步系統(二)
- 設計模式綜合實例分析之數據庫同步系統(三)