為子系統中的一組接口提供一個統一的高層接口,使得子系統更容易使用。
簡單來說,就是提供一個接口給客戶端使用,接口內包含眾多子系統的功能。比方說,當要找銀行貸款時,我們只需要找專員,而專員把我們的資料拿到後,要回銀行各部門跑流程,最後才能核貸給我們。行員就是接口,銀行各部門就是子系統。
成員 | 功用 |
---|---|
Facade | 為多個SubSystem對外提供的一個接口。 |
SubSystem | 系統各種不同的功能,Client透過Facade使用。 |
拿剛剛講的貸款的例子,銀行行員就是Facade的接口。而他裡面的SubSystem就是去各部門跑流程,為了完成客戶的貸款。
首先我們先將銀行各部門的系統給建立起來(由於本人不清楚貸款要跑哪些部門,所以用ABCD代替)
class Department_A {
public void method1() {
System.out.println("Data sent to the departmentA");
}
}
class Department_B {
public void method2() {
System.out.println("Data sent to the departmentB");
}
}
class Department_C {
public void method3() {
System.out.println("Data sent to the departmentC");
}
}
class Department_D {
public void method4() {
System.out.println("Data sent to the departmentD");
}
}
我們建立了ABCD四個子系統。現在需要一個Facade來把所有的子系統包裝起來:
class CommissionerFacade {
private Department_A obj1 = new Department_A();
private Department_B obj2 = new Department_B();
private Department_C obj3 = new Department_C();
private Department_D obj4 = new Department_D();
public void method() {
obj1.method1();
obj2.method2();
obj3.method3();
obj4.method4();
}
}
銀行專員就是Facade,將所有的子系統包裝在method()內,也就是說,由他去找各部門辦事情,Client不需要管。
最後Client將Facade建立起來並呼叫裡面的method(),來完成我們貸款的行為。
public class PCHome {
public static void main(String[] args) {
CommissionerFacade f = new CommissionerFacade();
f.method();
}
}
output
Data sent to the departmentA
Data sent to the departmentB
Data sent to the departmentC
Data sent to the departmentD
這就是Facade Pattern實作後的程式碼。UML可以看出,由專員處理一切事務,我們只需要對應專員即可,不需要知道銀行各部門到底在幹嘛。這看起來很簡單,但如果沒使用的話會長怎樣呢?
public class Bank {
public static void main(String[] args) {
Department_A obj1 = new Department_A();
Department_B obj2 = new Department_B();
Department_C obj3 = new Department_C();
Department_D obj4 = new Department_D();
obj1.method1();
obj2.method2();
obj3.method3();
obj4.method4();
}
如果沒有Facade,就像沒了專員,若要貸款就要自己去銀行各部門跑流程。這樣Client會直接相依到子系統,這樣若未來子系統需要做更動,可能會影響到Client端。這樣就違反了開閉原則。
為子系統中的一組接口提供一個統一的高層接口,使得子系統更容易使用。
Facade:統一的入口,如銀行專員。
SubSystem:各種系統,如銀行各部門。
優點
1. Client對只對Facade有關,與SubSystem無關,此模式迪米特法則的典型應用。
2. 降低SubSystem與Client間的耦合度,未來子系統若需要更新不需要異動到其他程式碼。
缺點
1. 無法限制Client使用SubSystem。
2. 增加新的SubSystem可能會需要修改Facade,違反OCP。
1. 為複雜的模組或子系統提供給外面呼叫的模組。
2. 子系統相對獨立。