http://www.cnblogs.com/sweetdream/archive/2005/12/19/299983.html
門面(Facade)模式和中介者(Mediator)模式有著共同的目的。它們都是調配一組相互耦合的對象的通訊。不過門面模式關注的是這組複雜物件如何與外界通訊,而中介者模式是調配這組複雜物件之間的通訊。
門面(Facade)模式
當想要為一組具有複雜且全面的介面對象提供一個簡單且特定的介面供外界使用時,就可以採用門面模式。
門面模式理解起來不難,但是要找到合適粒度的門面就不那麼容易了。[GOF95]中說:“一個常見的設計目標是使子系統間的通訊和相互依賴關係達到最小達到該目標的途徑之一就是引入一個門面對象,它為子系統中較一般的設施提供了一個單一而簡單的介面。”我覺得,雖然使用者不必直接和子系統中的類打交道了,但是通過門面也間接地和它們有所聯絡(這裡可能可以用Adapter模式隔離變化)。門面模式的主要目的我覺得不在於減少依賴關係(如果包括間接依賴),而是簡化使用者的使用介面。門面模式是有悖於介面隔離原則的。但是話說回來如果門面選擇的粒度合適的話那麼還是利大於弊的。
門面模式的應用:
當你要為一個複雜子系統提供一個簡單介面時。子系統往往因為不斷演化而變得越來越複雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系統進行定製,但這也給那些不需要定製子系統的使用者帶來一些使用上的困難。Facade可以提供一個簡單的預設視圖,這一視圖對大多數使用者來說已經足夠,而那些需要更多的可定製性的使用者可以越過Facade層。
引入Facade將這個子系統與客戶以及其他的子系統分離,可以提高子系統的獨立性和可移植性。
當你需要構建一個階層的子系統時,使用Facade模式定義子系統中每層的進入點,如果子系統之間是相互依賴的,你可以讓它們僅通過Facade進行通訊,從而簡化了它們之間的依賴關係。
門面模式的結構:
門面(Facade)角色:用戶端可以調用這個角色的方法。此角色知曉相關的(一個或者多個)子系統的功能和責任。在正常情況下,本角色會將所有從用戶端發來的請求委派到相應的子系統去。
子系統(subsystem)角色:可以同時有一個或者多個子系統。每一個子系統都不是一個單獨的類,而是一個類的集合。每一個子系統都可以被用戶端直接調用,或者被門面角色調用。子系統並不知道門面的存在,對於子系統而言,門面僅僅是另外一個用戶端而已。
注意,可以用抽象類別實現Façade而它的具體子類對應於不同的子系統實現,這可以進一步降低客戶與子系統得耦合度。這樣,客戶就可以通過抽象的Façade類介面與子系統通訊。這種抽象耦合關係使得客戶不知道它使用的是子系統得那一個實現。
中介者(Mediator)模式
用一個中介對象來封裝一系列對象(此模式中稱為Colleague)互動。中介者使各對象不需要顯示地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動(只須改變中介者類)。<<Java與模式>>中有個比較形象的例子,就是中國加入WTO後,與外國的貿易往來都不必和每個國家達成協商,而只要符合WTO的協議就可以了。WTO在這裡起了一個中介者的作用。
考慮一個表單,其中有很多控制項,Button,TextBox,ListBox等,這些控制項都是相互作用的,比如如果TextBox中沒有字元的話,那麼Button的狀態就為UnEnable,當改變ListBox的選項時,TextBox中會顯示ListBox中所選定的項。如果按常規設計這些對象之間的關係就會變得複雜而且不好管理,沒有第三者來組織它們,造成高度的耦合,最壞的情況下,每個對象都要知道其它的對象,可維護性大打折扣;而且要把相互作用的邏輯封裝到自己的類中,重用的可能性也就大打折扣了。
我們可以通過將集體行為封裝在一個單獨的中介者對象中以避免這個問題。中介者負責控制和協調一組對象間的互動。中介者充當一個中介以使組中的對象不再相互顯示引用。這些對象僅知道中介者,從而減少了相互串連的數目。
中介者模式的結構:
Mediator(中介者)
中介者定義一個介面用於與各同事(Colleague)對象通訊。
ConcreteMediator(具體中介者)
具體中介者通過協調各同事對象實現協作行為。
瞭解並維護它的各個同事。
Colleague(同事類)
每一個同事類都知道它的中介者對象。
每一個同事對象在需與其他的同事通訊的時候,僅僅與它的中介者通訊。
協作:同事向一個中介者對象發送和接收請求。中介者在各同事間適當地轉寄請求以實現協作行為。
從結構圖我們可以看出中介者知道所有同事類,從而才能調度它們,因此可以說中介者模式是將互動的複雜性變成中介者的複雜性。反過來每個同事類都知道它的中介者對象,這樣它才能當自己狀態改變時通知給中介者,從而影響其它的同事類。(這裡有兩種實現的方式1. 可以用到Observer模式;2. 在Mediator中定義一個特殊的通知介面,各Colleague在通訊時直接調用這個介面並將自身作為一個參數傳遞給Mediator,使其可以識別寄件者。 )。這樣的耦合性似乎和Façade模式一樣有悖於介面隔離原則的:如果一個同事類的介面改變,那麼中介者也將改變,從而使得所有的同事類都要改變。這裡是一個循環相依性,每個類介面的改變都可能造成所有類都改變。但是本模式的主要目的之一是簡化通訊方式,而不是隔離同事類的變化。我們看看GOF描述這個模式的適用性:
1.一組對象以定義良好(注意這裡說了是定義良好,如果同事類需要經常改變介面就要小心了)但是複雜的方式進行通訊。產生的相互依賴關係結構混亂且難以理解。
2.一個對象引用其他很多個物件並且直接與這些對象通訊,導致難以複用該對象。(一個對象如果和太多的其它對象相關聯就很難複用了)
3.想定製一個分布在多個類中的行為,而又不想產生太多的子類。(比如上面說的改變一個控制項的狀態就可以引起其它控制項的變化)
中介者模式的優點和缺點:
1.減少子類的產生 Mediator將原本分佈於多個對象間的行為集中在一起。改變這些行為只需產生Mediator的子類即可。
2.它將各Colleague解耦 Mediator有利於各Colleague類間的松耦合。你可以獨立的改變和複用各Colleague類和Mediator類。
3.它簡化了對象協議 用Mediator和各Colleague間的一對多的互動來替代多對多的互動。一對多的關係更易於理解。維護和擴充。
4.它對對象如何協作進行了抽象 將中介作為一個獨立的概念並將其封裝在一個對象中,使你將注意力從對象各自本身的行為轉移到他們之間的互動上來。這有助於弄清楚一個系統中的對象是如何互動的。
5.它使控制集中化 中介者模式將互動的複雜性變為中介者的複雜性。因為中介者封裝了協議,它可能比任何一個Colleague都複雜。這可能使得中介者自身成為一個難於維護的龐然大物。
Facade模式是解耦系統外到系統內(單向)的對象關聯關係,Mediator模式是解耦系統內各個對象之間在(雙向)的關聯關係