定義
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
用一箇中介對象封裝一系列的對象交互,中介者使各對象不需要顯示地相互作用,從而使用其耦合鬆散,而且可以獨立地改變它們之間的交互。
中介者模式能用類圖如下所示:
從類圖中看,中介者模式由以下幾部分組成:
-
Mediator抽象中介者角色
抽象中介者角色定義統一的接口,用於各同事角色之間的通信。 -
Concrete Mediator具體中介者角色
具體中介者角色通過協調各同事實現協作行爲,因此它必須依賴於各個同事角色。 -
Colleague同事角色
每一個同事角色都知道中介者角色,而且與其他的同事角色通信的時候,一定要通過中介者角色協作。每個同事的行爲分爲兩種:
第一種是同事本身的行爲,比如改變對象本身的狀態,處理自己的行爲等,這種方法叫做自發行爲(Self-Method),與其他的同事類或中介者沒有任何的依賴;
第二種是必須依賴中介者才能完成的行爲,叫做依賴方法(Dep-Method)。
通用抽象中介者類:
public abstract class Mediator {
// 定義同事類
protected ConcreteColleague1 c1;
protected ConcreteColleague2 c2;
// 通過getter、setter方法把同事類注入進來
public ConcreteColleague1 getC1() {
return c1;
}
public void setC1(ConcreteColleague1 c1) {
this.c1 = c1;
}
public ConcreteColleague2 getC2() {
return c2;
}
public void setC1(ConcreteColleague2 c2) {
this.c2 = c2;
}
// 中介者模式的業務邏輯
public abstract void doSomething1();
public abstract void doSomething2();
}
在Mediator抽象類中,我們只定義了同事類的注入,爲什麼使用同事實現類注入而不使用抽象類注入呢?
那是因爲同事類雖然有抽象,但是沒有每個同事類必須要完成的業務方法,當然如果每個同事類都有相同的方法,如execute,handler等,那當然注入抽象類,做到依賴倒置
。
具體的中介者一般只有一個,即通用中介者,其源代碼如下:
public class ConcreteMediator extends Mediator {
@Override
public void doSomething1() {
// 調用同事類的方法,只要是public方法都可以調用
supper.c1.selfMethod1();
supper.c2.selfMethod2();
}
@Override
public void doSomething2() {
// 調用同事類的方法,只要是public方法都可以調用
supper.c1.selfMethod1();
supper.c2.selfMethod2();
}
}
中介者所具有的方法doSomething1和doSomething2都是比較複雜的業務邏輯,爲同事類服務,其實現是依賴各個同事類來完成的。
抽象同事類:
public abstract class Colleagua {
protected Mediator mediator;
public Colleague(Mediator _mediator) {
this.mediator = _mediator;
}
}
具體同事類:
public class ConcreteColleague1 extends Colleague {
// 通過構造函數傳遞中介者
public ConcreteColleague1(Mediator _mediator) {
super(_mediator);
}
// 自有方法 self-method
public void selfMethod1() {
// 處理自己的業務邏輯
}
// 依賴方法 dep-method
public void depMethod1() {
//處理自己的業務邏輯
//自己不能處理的業務邏輯,委託給中介者處理
super.mediator.doSomething1();
}
}
同事類ConcreteColleague2也類似;
特點
- 優點 - 減少了類間的依賴,把原來的一對多的依賴變成了一對一的依賴,同事類保依賴中介者,減少了依賴,當然同時也降低了類間的耦合。
- 缺點 - 中介者會膨脹得很大,而且邏輯複雜,原本N個對象直接的相互依賴關係轉換爲中介者和同事類的依賴關係,同事類越多,中介者的邏輯就越複雜。
PS 中介者模式的使用需要量力而行,中介者模式適用於多個對象之間緊密耦合的情況,緊密耦合的標準是:在類圖中出現了蜘蛛網狀結構。在這種情況下一定要考慮使用中介者模式,這有利於把蜘蛛網梳理爲星形結構,使原本複雜混亂的關係變得清晰簡單。
實際應用場景
大家都應該熟悉的Structs,MVC框架,其中的C(Controller)
就是一箇中介者,叫做前端控制器(Front Controller),它的使用就是把M(Model,業務邏輯)
和V(View,視圖)
隔離開,協調M和V協同工作,把M運行的結果和V代表的視圖融合成一個前端可以展示的頁面,減少M和V的依賴關係。
最佳實踐
- N個對象之間產生了相互依賴的關係(N > 2)
- 多個對象有依賴關係,但是依賴的行爲尚不確定或者有發生改變的可能,在這種情況下一般建議採用中介者模式,降低變更引起的風險擴散。
- 產品開發。一個明顯的例子就是MVC框架,把中介者模式應用到產品中,可以提升產品的性能和擴展性,但是對於項目開發就未必,因爲項目是以交付投產爲目標,而產品則是以穩定、高效、擴展爲宗旨。