中介者模式的定義
中介者模式的定義為:
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)。
中介者模式的應用
中介者模式的優點
中介者模式的優點就是減少類間的依賴,把原有的一對多的依賴變成了一對一的依賴,同事類只依賴中介者,減少了依賴,當然同時也降低了類間的耦合。
中介者模式的缺點
中介者模式的缺點就是中介者會膨脹得很大,而且邏輯復雜,原本N個對象直接的相互依賴關系轉換為中介者和同事類的依賴關系,同事類越多,中介者的邏輯就越復雜。
中介者模式的使用場景
中介者模式簡單,但是簡單不代表容易使用,很容易被誤用。在面向對象的編程中,對象和對象之間必然會有依賴關系,如果某個類和其他類沒有任何相互依賴的關系,那這個類就是一個“孤島”,在項目中就沒有存在的必要了!
類之間的依賴關系是必然存在的,一個類依賴多個類的情況也是存在的,存在即合理,那是否可以說只要有多個依賴關系就考慮使用中介者模式呢?答案是否定的。
中介者模式未必能幫你把原本凌亂的邏輯整理得清清楚楚,而且中介者模式也是有缺點的,這個缺點在使用不當時會被放大,比如原本就簡單的幾個對象依賴關系,如果為了使用模式而加入了中介者,必然導致中介者的邏輯復雜化,因此中介者模式的使用需要“量力而行”!
中介者模式適用于多個對象之間緊密耦合的情況,緊密耦合的標準是:在類圖中出現了蜘蛛網狀結構。在這種情況下一定要考慮使用中介者模式,這有利于把蜘蛛網梳理為星型結構,使原本復雜混亂的關系變得清晰簡單。
中介者模式的實際應用
中介者模式也叫做調停者模式,是什么意思呢?一個對象要和N多個對象交流,就像對象間的戰爭,很混亂。這時,需要加入一個中心,所有的類都和中心交流,中心說怎么處理就怎么處理。
最佳實踐
本章講述的中介者模式很少用到接口或者抽象類,這與依賴倒置原則是沖突的,這是什么原因呢?
首先,既然是同事類而不是兄弟類(有相同的血緣),那就說明這些類之間是協作關系,完成不同的任務,處理不同的業務,所以不能在抽象類或接口中嚴格定義同事類必須具有的方法(從這點也可以看出繼承是高侵入性的)。這是不合適的,就像你我是同事,雖然我們家都是朝九晚五地上班,但是你跟我干的活肯定不同,不可能抽象出一個父類統一定義同事所必須有的方法。
中介者模式是一個非常好的封裝模式,也是一個很容易被濫用的模式,一個對象依賴幾個對象是再正常不過的事情,但是純理論家就會要求使用中介者模式來封裝這種依賴關系,這是非常危險的!
使用中介模式就必然會帶來中介者的膨脹問題,這在一個項目中是很不恰當的。
可以在如下的情況下嘗試使用中介者模式:
N個對象之間產生了相互的依賴關系(N> 2)。
多個對象有依賴關系,但是依賴的行為尚不確定或者有發生改變的可能,在這種情況下一般建議采用中介者模式,降低變更引起的風險擴散。
產品開發。一個明顯的例子就是MVC框架,把中介者模式應用到產品中,可以提升產品的性能和擴展性,但是對于項目開發就未必,因為項目是以交付投產為目標,而產品則是以穩定、高效、擴展為宗旨。