一、外觀模式的定義
外觀(Facade)模式的定義:又叫門面模式,是一種通過為多個復雜的子系統提供一個一致的接口,而使這些子系統更加容易被訪問的模式。該模式對外有一個統一接口,外部應用程序不用關心內部子系統的具體的細節,這樣會大大降低應用程序的復雜度,提高了程序的可維護性。
二、外觀模式優缺點
優點:
- 簡化了調用過程,無需了解深入子系統,防止帶來風險
- 減少系統依賴、松散耦合
- 更好的划分訪問層次
- 符合迪米特法則,即最少知道原則
缺點:
- 增加子系統、擴展子系統行為容易引入風險
- 不符合開閉原則
三、外觀模式的實現
外觀(Facade)模式的結構比較簡單,主要是定義了一個高層接口。它包含了對各個子系統的引用,客戶端可以通過它訪問各個子系統的功能。現在來分析其基本結構和實現方法。
外觀(Facade)模式包含以下主要角色。
- 外觀(Facade)角色:為多個子系統對外提供一個共同的接口。
- 子系統(Sub System)角色:實現系統的部分功能,客戶可以通過外觀角色訪問它。
- 客戶(Client)角色:通過一個外觀角色訪問各個子系統的功能。
其結構圖如圖所示:

代碼常見有兩種情況都是屬於外觀模式,如下代碼:
所有子系統實現統一接口:
public interface System { public void dosomething(); } public class SubSystemA implements System { public void dosomething() { System.out.println("子系統方法A"); } } public class SubSystemB implements System { public void dosomething() { System.out.println("子系統方法B"); } } public class Facade { //被委托的對象 System a,b; public Facade() { a = new SubSystemA(); b = new SubSystemB(); } //提供給外部訪問的方法 public void methodA() { this.a.dosomething(); } public void methodB() { this.b.dosomething(); } } public class Client { public static void main(String[] args) { Facade facade = new Facade(); facade.methodA(); facade.methodB(); } }
所有子系統未實現統一接口:
public class SubSystemA { public void dosomethingA() { System.out.println("子系統方法A"); } } public class SubSystemB { public void dosomethingB() { System.out.println("子系統方法B"); } } public class Facade { //被委托的對象 SubSystemA a; SubSystemB b; public Facade() { a = new SubSystemA(); b = new SubSystemB(); } //提供給外部訪問的方法 public void methodA() { this.a.dosomethingA(); } public void methodB() { this.b.dosomethingB(); } } public class Client { public static void main(String[] args) { Facade facade = new Facade(); facade.methodA(); facade.methodB(); } }
測試結果如下:
子系統方法A
子系統方法B
四、外觀模式的應用場景
通常在以下情況下可以考慮使用外觀模式。
- 子系統越來越復雜,增加外觀模式提供簡單接口調用
- 構建多層系統結構,利用外觀對象作為每層的入口,簡化層間調用
五、外觀模式的擴展
在外觀模式中,當增加或移除子系統時需要修改外觀類,這違背了“開閉原則”。如果引入抽象外觀類,則在一定程度上解決了該問題,其結構圖如圖所示:
代碼如下:
public class FacadePattern { public static void main(String[] args) { Facade f=new FacadeImpl1(); f.method(); f=new FacadeImpl2(); f.method(); } } interface Facade { public void method(); } //外觀角色 class FacadeImpl1 implements Facede { private SubSystem01 obj1=new SubSystem01(); private SubSystem02 obj2=new SubSystem02(); private SubSystem03 obj3=new SubSystem03(); public void method() { obj1.method1(); obj2.method2(); obj3.method3(); } } //外觀角色 class FacadeImpl1 implements Facede { private SubSystem02 obj2=new SubSystem02(); private SubSystem03 obj3=new SubSystem03(); private SubSystem04 obj4=new SubSystem04(); public void method() { obj2.method2(); obj3.method3(); obj4.method4(); } } //子系統角色 class SubSystem01 { public void method1() { System.out.println("子系統01的method1()被調用!"); } } //子系統角色 class SubSystem02 { public void method2() { System.out.println("子系統02的method2()被調用!"); } } //子系統角色 class SubSystem03 { public void method3() { System.out.println("子系統03的method3()被調用!"); } } //子系統角色 class SubSystem04 { public void method4() { System.out.println("子系統04的method4()被調用!"); } }
