一、外觀模式定義
外觀模式又稱爲門面模式,它通過引入一個外觀角色來簡化客戶端與子系統之間的交互,爲複雜的子系統調用提供一個統一的入口,降低子系統與客戶端的耦合度,且客戶端調用非常方便。
二、外觀模式的結構和說明
不用外觀模式的情況下,Client需要跟子系統的多個模塊進行交互,這就要求Client對各個模塊都比較瞭解,這種情況耦合度較高,並且對子系統的調用也比較複雜。
使用外觀模式的情況下,Facade對子系統內的模塊進行了封裝。Client直接跟Facade層進行交互,無需關心各個模塊是怎麼實現的,減少了跟各個模塊的交互,鬆散耦合,使調用變得更簡單。
三、外觀模式示例
假設有這樣一個需求:我們需要根據數據庫表,動態的生成對應的Controller、Service、Dao層基本增刪改查代碼。
Controller層生成器模塊
/**
* Controller層生成器
*/
public class ControllerGenerator {
/**
* 生成Controller層代碼文件
*/
public void generator(){
System.out.println("生成文件:Controller.java");
}
}
Service層生成器模塊
/**
* Service層生成器
*/
public class ServiceGenerator {
/**
* 生成Service層代碼文件
*/
public void generator(){
System.out.println("生成文件:Service.java");
}
}
Dao層生成器模塊
/**
* Dao層生成器
*/
public class DaoGenerator {
/**
* 生成Dao層代碼文件
*/
public void generator(){
System.out.println("生成文件:Dao.java");
}
}
以上是子系統的各個模塊,接下來定義外觀層模塊
外觀層模塊
/**
* 定義生成代碼的外觀層
*/
public class GenetatorFacade {
/**
* 私有構造器
* 外觀層一般只是對子系統各個模塊的一個封裝和組合,通常可以實現成單例,或者直接將方法定義爲靜態方法
*/
private GenetatorFacade() {
}
/**
* 生成需要的代碼文件(對子系統各模塊功能的包裝)
*/
public static void genetator(){
// 生成Controller層代碼文件
new ControllerGenerator().generator();
// 生成Service層代碼文件
new ServiceGenerator().generator();
// 生成Dao層代碼文件
new DaoGenerator().generator();
}
}
以上,外觀模式的結構就已經定義好了,下邊我們來模擬一下使用。
public class Client {
public static void main(String[] args) {
// 生成代碼
GenetatorFacade.genetator();
}
}
執行main方法後,得到下邊的輸出:
生成文件:Controller.java
生成文件:Service.java
生成文件:Dao.java
四、外觀模式的優缺點
優點:
- 鬆散耦合。 外觀模式鬆散了客戶端與子系統之間的耦合關係,使子系統模塊更容易擴展和維護。
- 簡單易用。 客戶端不需要了解子系統內部各模塊的具體實現,只要跟外觀層交互,委託外觀層去實現即可。
- 更好的劃分訪問層次。 子系統中有些方法是對系統外的,有些方法是系統內部使用的。通過外觀層將對系統外的暴露出去,而將對內的隱藏,這樣防止客戶端發現一些不需要它知道的方法,造成迷惑和“接口污染”。
五、外觀模式的應用場景
- 如果訪問的子系統很複雜,增加外觀模式提供一個簡單的調用接口。
- 如果希望客戶端和子系統之間實現松耦合,可以考慮用外觀模式將它們隔離,從而提供子系統的獨立性和可移植性。