定義
又叫門面模式,提供了一個統(tǒng)一的接口,用來訪問子系統(tǒng)中的一群接口。
定義了一個高層接口,讓子系統(tǒng)更容易使用。
適用場景
- 子系統(tǒng)越來越復雜,增加外觀模式提供簡單調(diào)用接口。
- 構(gòu)建多層系統(tǒng)結(jié)構(gòu),利用外觀對象作為每層的入口,簡化層間調(diào)用。
優(yōu)點
- 簡化了調(diào)用過程,無需了解深入子系統(tǒng),防止帶來風險。
- 減少系統(tǒng)依賴,松散耦合。
- 更好的劃分訪問層次。
- 符合迪米特法則。
缺點
- 增加子系統(tǒng),擴展子系統(tǒng)行為容易引入風險。
- 不符合開閉原則。
代碼
我們下面來實現(xiàn)這么一個業(yè)務(wù)場景,在我們網(wǎng)上購買商品時,會有這么一個簡單流程
- 檢查是否有庫存,是否可以進行購買
- 購買,付款
- 扣庫存
- 購買成功
- 物流系統(tǒng)
我們要實現(xiàn)這個簡單的流程需要3個服務(wù)以及一個上層接口服務(wù)。下面我們就來看一下使用外觀模式下的購買流程。
檢查庫存服務(wù)--StockService
庫存服務(wù)包括檢查庫存和扣除庫存。
/**
* 庫存服務(wù)
*/
public class StockService {
/**
* 檢查是否有庫存
* @param serNo 商品序列號
* @return
*/
public boolean haveStock(String serNo) {
System.out.println("檢查商品系列號為:" + serNo +"的商品是否有貨");
return true;
}
public boolean reduce(String serNo) {
System.out.println("扣庫存,商品號為:" + serNo);
return true;
}
}
付款服務(wù) -- PayService
/**
* 付款服務(wù)
*/
public class PayService {
/**
* 付款服務(wù)
* @param money 付款錢數(shù)
* @return
*/
public boolean pay(String money) {
System.out.println("成功支付:" + money + "元");
return true;
}
}
物流服務(wù) -- DeliveryService
/**
* 物流服務(wù)
*/
public class DeliveryService {
public String isDelivery(String SerNo) {
String id = "007";
System.out.println("商品發(fā)貨,訂單號為:" + id);
return id;
}
}
上層服務(wù)(外觀者模式接口服務(wù))--ShoppingTopService
/**
* 上層服務(wù)
*/
public class ShoppingTopService {
private DeliveryService deliveryService;
private PayService payService;
private StockService stockService;
/**
* 模擬pring 構(gòu)造注入
*/
public ShoppingTopService() {
this.deliveryService = new DeliveryService();
this.payService = new PayService();
this.stockService = new StockService();
}
public void buy(String serNo) {
if(stockService.haveStock(serNo)) { //檢查庫存
if(payService.pay("10000")) { //付款
if(stockService.reduce(serNo)) { //扣庫存
String deliveryId = deliveryService.isDelivery(serNo); //物流服務(wù)
System.out.println("交易完成,發(fā)貨完成,物流號: " + deliveryId);
}
}
}
}
}
啟動 -- FacadeBootStrap
public class FacadeBootStrap {
public static void main(String[] args) {
ShoppingTopService shoppingTopService = new ShoppingTopService();
shoppingTopService.buy("9999");
}
}
輸出

facade.jpg
UML 類圖

facadeUMl.jpg
通過類圖我們可以明顯看到外觀模式的優(yōu)點。
小結(jié)
不光是tomcat 例如Spring,Mybatis中也有很多對應(yīng)的外觀模式的實現(xiàn)。在我們閱讀源碼的過程中,稍加注意就可以找到。