外部與一個子系統的通信必須通過一個統一的外觀(Facade)對象進行,這就是外觀模式。
- 外觀模式要求一個子系統的外部與其內部的通信必須通過一個統一的外觀(Facade)對象進行。外觀模式提供一個高層次的接口,是的子系統更易於使用。
- 外觀模式的外觀類將客戶端與子系統的內部複雜性分隔開,使得客戶端只需要與外觀對象打交道,而不需要與子系統內部的很多對象打交道。
外觀模式的結構
- 外觀(Facade)角色
客戶端可以調用這個角色的方法。此角色知曉相關的(一個或者多個)子系統的功能和責任。在正常情況下,本角色會將所有從客戶端發來的請求委派到相應的子系統去。 - 子系統(subsystem)角色
可以同時有一個或者多個子系統。每一個子系統都不是一個單獨的類,而是一個類的集合。每一個子系統都可以被客戶端直接調用,或者被門面角色調用。子系統並不知道門面的存在,對於子系統而言,門面僅僅是另外一個客戶端而已。
【GOF】的書中指出
在外觀模式中,通常只需要一個外觀類,並且此外觀類只有一個實例,換言之它是一個單例類。當然這並不意味着在整個系統裏只能有一個外觀類,而僅僅是說對每一個子系統只有一個外觀類。或者說,如果有一個系統有好幾個子系統的話,每一個子系統有一個外觀類,整個系統可以有數個外觀類。
當客戶程序與抽象類的實現部分之間存下着很大的依賴性,引入Facade將這個子系統與客戶一集其他的子系統分離,爲一個複雜子系統提供一個簡單接口,Facade可以提供一個簡單地缺省視圖,這一視圖對大多數用戶來說已經足夠,而那些需要更多的可定製性的用戶可以越過Facade層。可以提高子系統的獨立性和可移植性。
- 在層次化結構中,可以使用Facade模式定義系統中每一層的入口點,如果子系統之間是相互依賴的,則可以讓他們僅通過Facade進行通信,從而簡化他們之間的依賴關係。
- 希望包裝或隱藏原有系統:Facade可以把原有系統作爲自己的私有成員。原有系統與Facade類聯繫在一起,但使用Facade類的客戶無法看到原有的系統。
維護一個一流的大型系統。
跟蹤對系統的使用——強迫所有客戶通過Facade使用原有系統。
優點
- 屏蔽了外部客戶端和系統每部模塊的交互
- Facade的功能可以被多個客戶端調用,可以實現複用(功能的共享)
- 對使用Facade的人員來說,Facade大大的節省了他們的學習成本。
缺點
不符合開閉原則。
本質
封裝交互、簡化調用
就是將各種方法封裝到門面類中,用戶只能看到門面類,也不需要知道真實的方法類,做到了隔離。
實現:
public class ModuleA {
//示意方法
public void MethodA(){
System.out.println("調用ModuleA中的MethodA方法");
}
}
public class ModuleB {
//示意方法
public void MethodB(){
System.out.println("調用ModuleB中的MethodB方法");
}
}
public class ModuleC {
//示意方法
public void MethodC(){
System.out.println("調用ModuleC中的MethodC方法");
}
}
門面角色類:
public class Facade {
//示意方法,滿足客戶端需要的功能
ModuleA a;
ModuleA b;
ModuleA c;
Facade(){
a = new ModuleA();
b = new ModuleB();
c = new ModuleC();
}
public void MethodA(){
a.MethodA();
b.MethodB();
}
public void MethodB(){
b.MethodB();
c.MethodC();
}
}
客戶端角色類:
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.MethodA();
facade.MethodB();
}
}