假設我們需要開發一個坦克模擬系統用於模擬坦克車在各種作戰環境中的行為,其中坦克系統由引擎、控制器、車輪、車身等各子系統構成。
public class Wheel
...{
public void WAction1()
...{
}
public void WAction2()
...{
}
}
public class Engine
...{
public void EAction1()
...{
}
public void EAction2()
}
}
public class Bodywork
...{
public void BAction1()
...{
}
public void BAction2()
...{
}
}
public class Controller
...{
public void CAction1()
}
public void CAction2()
...{
}
}
如果我們在客戶程序中直接使用這幾個類,那麼就造成了這幾個類和客戶程序之間的緊耦合,那麼我們Facade的動機就是:組件的客戶和組件中各種復雜的子系統有了過多的耦合,隨著外部客戶程序和各子系統的演化,這種過多的耦合面臨很多變化的挑戰。如何簡化外部客戶程序和系統間的交互接口?如何將外部客戶程序的演化和內部子系統的變化之間的依賴相互解耦?
Facade模式的意圖:
為子系統中的一組接口提供一個一致的界面,Façade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
我們將上面四個類進行重組一下,由一個類來提供接口,這個類的方法就是實現四個類方法的接口
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()
...{
}
}
我們將這四個類封裝到TankFacade類裡,通過TankFacade類的方法來調用這四個類的方法,當四個類發生變化,我們客戶端程序仍然調用的是TankFacade類的方法,不需要重新修改客戶端程序的代碼。
注意:我們的目標並不是把所有的類都放在Facade類裡,通過Facade類來調用其他類的代碼。這樣理解Facade類是錯誤的,我們是將有關聯的,並且相互作用的類放在Facade類裡。
Facade模式的幾個要點: