文章目錄
Gof定義
為子系統中的一組介面提供一個一致的介面,Façade模式定義了一個高層介面,這個介面使得這一子系統更加容易使用。
先來看個小例子,假設我們需要開發一個坦克類比系統用於類比坦克車在各種作戰環境中的行為,其中坦克系統由引擎、控制器、車輪、車身等各子系統構成。就會有下面這些類的產生
public class Wheel{ }public class Engine{ }public class Controller{ }public class BodyWork{ }
不同的情境中的要求都不一樣,可能會用到某些子系統,也可能不會用到,這些不同的情境就相當是外部介面,這些情境和子系統的關係如:
圖1
中的關係感覺很混亂,情境和子系統之間的耦合度很高,要降低這種耦合度,就要使和情境之間互動的不是這些子系統了,而是相對單一的一個中介層,如:
圖2
的Facade就將子系統隱藏了,不同的情境都是直接和Facade互動。
動機
上面圖1方案的問題在於組件的客戶和組件中各種複雜的子系統有了過多的耦合,隨著外部客戶程式和各子系統的演化,這種過多的耦合面臨很多變化的挑戰。如何簡化外部客戶程式和系統間的互動介面?如何將外部客戶程式的演化和內部子系統的變化之間的依賴相互解耦?這就要用到Facade模式,先來看結構圖:
代碼實現,先定義一些子系統類
public class Wheel{ public void WAction1() { } public void WAction2() { }}public class Engine{ public void EAction1() { } public void EAction2() { }}public class Controller{ public void CAction1() { } public void CAction2() { }}public class BodyWork{ public void BAction1() { } public void BAction2() { }}
Facade類,用來組合這些子系統
public class TankFacade{ Wheel[] wheels = new Wheel[4]; Engine[] engines = new Engine[4]; BodyWork bodywork = new BodyWork(); Controller controller = new Controller(); public void Start() { //用到子系統中的一個或多個 } public void Stop() { //用到子系統中的一個或多個 } public void Run() { //用到子系統中的一個或多個 } public void Shot() { //用到子系統中的一個或多個 }}
用戶端調用
public class App{ static void Main() { TankFacade facade = new TankFacade(); //可以根據不同情境的需要來選擇調用相應的方法 //在客戶處之需要使用Facade就可以,不需要知道子系統的實現 //就起到了和子系統解耦的作用 facade.Start(); facade.Run(); facade.Shot(); facade.Stop(); }}Facade模式的幾個要點
從客戶程式的角度來看, Facade模式不僅簡化了整個組件系統的介面,同時對於組件內部與外部客戶程式來說,從某種程度上也達到了一種“解耦”的效果——內部子系統的任何變化不會影響到Façade介面的變化。
Façade設計模式更注重從架構的層次去看整個系統,而不是單個類的層次。Façade很多時候更是一種架構設計模式。
注意區分Façade模式、Adapter模式、Bridge模式與Decorator模式。Façade模式注重簡化介面,Adapter模式注重轉換介面,Bridge模式注重分離介面(抽象)與其實現,Decorator模式注重穩定介面的前提下為對象擴充功能。
返回開篇(索引)