門面模式
一:門面模式概述
在現實世界中,外牆都在我們身邊。作業系統就是這樣一個例子 - 您沒有看到計算機的所有內部工作方式,但作業系統提供了使用機器的簡化介面。簡而言之,門面模式旨在使事物看起來更清潔,更容易操作。
定義:為子系統中的一組介面提供統一介面。Façade定義了一個更高階別的介面,使子系統更易於使用。
門面模式只是將客戶端與子系統隔離,結構圖如下:
角色:
-
**Facade(外觀角色):**在客戶端可以呼叫它的方法,在外觀角色中可以知道相關的(一個或者多個)子系統的功能和責任;在正常情況下,它將所有從客戶端發來的請求委派到相應的子系統去,傳遞給相應的子系統物件處理。
-
SubSystem(子系統角色):在軟體系統中可以有一個或者多個子系統角色,每一個子系統可以不是一個單獨的類,而是一個類的集合,它實現子系統的功能;每一個子系統都可以被客戶端直接呼叫,或者被外觀角色呼叫,它處理由外觀類傳過來的請求;子系統並不知道外觀的存在,對於子系統而言,外觀角色僅僅是另外一個客戶端而已。
與介面卡模式一樣,Facade可用於隱藏第三方庫或某些遺留程式碼的內部工作方式。客戶端需要做的就是與Facade互動,而不是它所包含的子系統.
二 :門面模式實戰
某購物系統需要使用者登入支付,客戶端不清楚裡面會呼叫哪些系統,它只管提供負責呼叫購買方法來達到購買的目的。
登入子系統:
// 登入子系統
public class Login {
public void Login(String username, String password){
// 登入相關
}
}
複製程式碼
生成訂單子系統:
//生成訂單子系統
public class Order {
public void createOrder(String userName){
// 生成訂單相關
}
}
複製程式碼
支付子系統:
// 支付子系統
public class Pay {
public void payOrder(String username){
// 支付相關
System.out.println("尊敬的" + username + ",您的商品購買成功" + ";請保管好您的訂單號:"
+ UUID.randomUUID().toString());
}
}
複製程式碼
購買外觀類:
// 購買外觀類
public class ShopingFacade {
private Login loginHelp;
private Order orderHelp;
private Pay payHelp;
public ShopingFacade(){
this.loginHelp = new Login();
this.orderHelp = new Order();
this.payHelp = new Pay();
}
// 使用者購買商品
public void shop(String userName, String password){
loginHelp.Login(userName, password);
orderHelp.createOrder(userName);
payHelp.payOrder(userName);
}
}
複製程式碼
客戶端:
public class Client {
public static void main(String[] args) {
// 購買外觀類,客戶端並不知道里面呼叫了登入,訂單和支付子系統
ShopingFacade shopingFacade = new ShopingFacade();
shopingFacade.shop("tom", "123");
}
}
複製程式碼
執行結果:
尊敬的tom,您的商品購買成功;請保管好您的訂單號:438e379c-2c03-4579-b732-8bd23daf8e0b
在整個例項中,外觀類對客戶端遮蔽了3個子系統,減少了客戶端要處理的物件,使得客戶端程式碼變得很簡單。
三:門面模式總結
優勢:
使客戶端和子系統隔離,客戶端程式碼變得很簡單,不需要跟多個子系統進行關聯。
子系統的變化不會影響客戶端的程式碼。
子系統直接鬆耦合,一個系統的修改對其他系統沒有影響。
劣勢:
增加新的子類系統需要可能需要修改外觀類的原始碼,違背開閉原則。
使用場景
當要為訪問一系列複雜的子系統提供一個簡單入口時可以使用外觀模式。
客戶端程式與多個子系統之間存在很大的依賴性。引入外觀類可以將子系統與客戶端解耦,從而提高子系統的獨立性和可移植性。
在層次化結構中,可以使用外觀模式定義系統中每一層的入口,層與層之間不直接產生聯絡,而通過外觀類建立聯絡,降低層之間的耦合度。