設計介面時,為了有更高的重複使用性,會讓職責盡量單一、粒度小;但對使用者來說,要呼叫很多個介面才能完成,顯得特別麻煩。
Facade Pattern 把多個介面整合,提供統一、高階的介面,讓子系統更容易使用;子系統的概念,可以有多種理解,外部系統、介面、類別等等。
Facade Pattern 實作
Client 必須呼叫複雜的方法
public class A {
public void a1() { /*...*/ }
public void a2() { /*...*/ }
}
public class B {
public void b1() { /*...*/ }
public void b2() { /*...*/ }
}
public class Client {
private A a;
private B b;
public Client(A a, B b) {
this.a = a;
this.b = b;
}
public void execute() {
a.a1();
a.a1();
b.b1();
b.b2();
}
}
使用 Facade Pattern 重構
public class A {
/* same */
}
public class B {
/* same */
}
public class Facade {
private A a;
private B b;
public Facade(A a, B b) {
this.a = a;
this.b = b;
}
public void execute() {
a.a1();
a.a1();
b.b1();
b.b2();
}
}
public class Client {
private Facade facade;
public Client(Facade facade) {
this.facade = facade;
}
public void execute() {
facade.execute();
}
}
優點
- Client 更簡單的使用介面
- Client 與底層 A、B 類別鬆耦合
- 底層實現 A、B 的修改,或是執行過程的修改,不需要改動 Client 程式碼
補充說明,Facade Pattern 並不是封裝介面,而是簡化介面,如果想要直接使用底層的介面,請自便。
Facade Pattern v.s. Adapter Pattern
設計模式單純看程式碼實作,很多都相當類似,但從「設計意圖」去區別,會發現各模式要解決的問題都不一樣。
Facade Pattern 與 Adapter Pattern 實作的部分類似,二者都是對介面進行封裝;但 Facade Pattern 目的是簡化介面,Adapter Pattern 是轉接介面,去符合另一個系統的設計。
很多人會有一個誤區,認為 Facade Pattern 是把多個介面簡化成一個,而 Adapter Pattern 是把一個介面轉接成另一個,因為通常範例都長這樣,所以用處理一個或多個介面來區分這二種模式;其實 Facade Pattern 也可以只對一個複雜的介面簡化,Adapter Pattern 也可以轉接多個介面,以符合某一個 client 的介面,還是要回歸設計意圖上去思考。