Facade模式
一、定義
爲子系統中的一組接口提供一個統一接口。Facade模式定義了一個更高層的接口,使子系統更加容易使用。
二、例子1
大致意思是說:使用一種比原有方式更簡單的辦法與系統交互。例如,我們把一個很文件的文件,放在了第二抽屜裏,而第二個抽屜的鑰匙放在了第一個抽屜裏,我們要想取出這個文件,第一步肯定要拿到第一個抽屜的鑰匙,然後打開它再拿出第二個抽屜的鑰匙,最後打開第二個抽屜取出文件。
我就上面說的那個情形寫一下實現代碼,首先我們要實現二個子系統,呵呵,把抽屜比喻成系統,(DrawerOne、DrawerTwo):
子系統1
class DrawerOne {
public void open() {
System.out.println("第一個抽屜被打開了");
getKey();
}
public void getKey() {
System.out.println("得到第二個抽屜的鑰匙");
}
}
子系統2
class DrawerTwo {
public void open() {
System.out.println("第二個抽屜被打開了");
getFile();
}
public void getFile() {
System.out.println("得到這個重要文件");
}
}
不使用Façade模式的情況
public class Client {
public static void main(String[] args) {
DrawerOne darwerOne = new DrawerOne();
DrawerTwo darwerTwo = new DrawerTwo();
darwerOne.open();
darwerTwo.open();
}
}
由於沒有使用Façade模式,可以看到要想得到這個文件要首先打開第一個抽屜,然後再打開第二個抽屜,在我們實際所開發的系統中,有時候客戶要實現某一操作,並不需要知道實現這一操作的詳細步驟,而是簡單地點擊某一個按鈕就可以得到自己想要的結果。
使用Façade模式進行改進,建立一個FacadeDrawer類:
class DrawerFacade {
DrawerOne darwerOne = new DrawerOne();
DrawerTwo darwerTwo = new DrawerTwo();
public void open() {
darwerOne.open();
darwerTwo.open();
}
}
修改Client類:
public class DrawerClient{
public static void main(String []args){
DrawerFacade drawer=new DrawerFacade();
drawer.open();
}
}
輸出結果如下:
第一個抽屜被打開了 得到第二個抽屜的鑰匙 第二個抽屜被打開了 得到這個重要文件 |
正如上面所說,客戶端client,它並不需要關心子系統,而是關心DrawerFacade所留下來的和外部交互的接口,而子系統在DrawerFacade的聚合。
三、例子2
A系統有A1, A2, A3等類。客戶端需要調用A系統的的A1.doSomething1();A2.doSomething2();A3.doSomething3()三個方法來完成某功能。Facade模式的實現模型就是:
A1
class A1 {
public void doSomething1() {}
}
A2
class A2 {
public void doSomething2() {}
}
A3
class A3 {
public void doSomething3() {}
}
Facade:
public class Facade {
public void doSomething() {
A1 a1 = new A1();
A1 a2 = new A2();
A1 a3 = new A3();
a1.doSomething1();
a2.doSomething2();
a3.doSomething3();
}
}
Client:
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.doSomething();
}
}
四、適用性
Facade模式主要適用於以下幾種情況:
1. 爲一個複雜子系統提供一個簡單接口。
當你要爲一個複雜子系統提供一個簡單接口時。子系統往往因爲不斷演化而變得越來越複雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系統進行定製,但這也給那些不需要定製子系統的用戶帶來一些使用上的困難。Facade 可以提供一個簡單的缺省視圖,這一視圖對大多數用戶來說已經足夠,而那些需要更多的可定製性的用戶可以越過facade層。
2.提高子系統的獨立性
客戶程序與抽象類的實現部分之間存在着很大的依賴性。引入facade 將這個子系統與客戶以及其他的子系統分離,可以提高子系統的獨立性和可移植性。
3.在層次化結構中,可以使用Facade模式定義系統中每一層的入口。
當你需要構建一個層次結構的子系統時,使用facade模式定義子系統中每層的入口點。如果子系統之間是相互依賴的,你可以讓它們僅通過facade進行通訊,從而簡化了它們之間的依賴關係。
4.希望使用原系統的功能,而且還希望增加一些新的功能。
五、Facade的幾個要點
從客戶程序的角度來看,Facade模式不僅簡化了整個組件系統的接口,同時對於組件內部與外部客戶程序來說,從某種程度上也達到了一種“解耦”的效果——內部子系統的任何變化不會影響到Façade接口的變化。
Façade設計模式更注重從架構的層次去看整個系統,而不是單個類的層次。Façade很多時候更是一種架構設計模式。
Façade設計模式並非一個集裝箱,可以任意地放進任何多個對象。Façade模式中組件的內部應該是“相互耦合關係比較大的一系列組件”,而不是一個簡單的功能集合。
注意區分Façade模式、Adapter模式、Bridge模式與Decorator模式。Façade模式注重簡化接口,Adapter模式注重轉換接口,Bridge模式注重分離接口(抽象)與其實現,Decorator模式注重穩定接口的前提下爲對象擴展功能。