自己在家開網(wǎng)站做推廣百度優(yōu)化關(guān)鍵詞
目錄導(dǎo)航
- 什么是外觀模式
- 現(xiàn)實生活類比
- 實戰(zhàn)示例
- 門面模式的好處
- 門面模式源碼舉例
什么是外觀模式
外觀模式的英文名是Facade,意思是the front of a building,即建筑物的正面(門面),我個人更喜歡翻譯成門面模式。門面模式是一種結(jié)構(gòu)型設(shè)計模式,所謂結(jié)構(gòu)型是指在代碼結(jié)構(gòu)設(shè)計方面的設(shè)計模式。
門面模式是一個類或一個模塊統(tǒng)一的功能入口,屏蔽掉系統(tǒng)內(nèi)部的實現(xiàn)及運(yùn)作方式,客戶端通過門面與系統(tǒng)交互,大大降低使用的復(fù)雜度,減少與系統(tǒng)的耦合。
現(xiàn)實生活類比
在一家餐館中,顧客可能需要各種服務(wù)。如:點餐、買單、詢問衛(wèi)生間、需要衛(wèi)生紙、臨時添加碗筷等等。如果每種服務(wù)都要到餐館不同的服務(wù)點找不同的人解決,顧客會瘋掉。而前臺就是整個餐館的門面,是餐館所有功能的輸出口,顧客通過前臺與餐館溝通,享受各種服務(wù),而不用關(guān)心前臺將會對此事如何安排(具體指派何人,以何種方式滿足顧客要求等)。
實戰(zhàn)示例
假如,我們要開發(fā)上述的餐館功能。
初始階段,業(yè)務(wù)相對簡單,我們只有點餐與買單的功能。新建一個OrderManager類,
public class OrderManager {//點餐public void order(int tableNo) {System.out.println("table " + tableNo + " has ordered");}//買單public void bill(int tableNo, double dollars) {System.out.println("table " + tableNo + " bill:" + dollars);}
}
調(diào)用方使用該功能,
public static void main(String[] args) {//創(chuàng)建訂單管理模塊OrderManager orderManager = new OrderManager();//下單orderManager.order("001");//結(jié)賬orderManager.bill("001", 350.00);}
隨著業(yè)務(wù)迭代,我們又提供了一些詢問服務(wù),置于QueryService中,
public class QueryService {//衛(wèi)生間在哪里public String whereToilet(){return "it's xxxxx";}//...
}
隨著業(yè)務(wù)的復(fù)雜,我們不斷加入新的功能置于新的模塊。對于餐館功能的使用方來說,需要記住每個功能模塊對應(yīng)的類,使用復(fù)雜度不斷攀升。
public static void main(String[] args) {//創(chuàng)建訂單管理模塊OrderManager orderManager = new OrderManager();//下單orderManager.order("001");//結(jié)賬orderManager.bill("001", 350.00);//創(chuàng)建服務(wù)問詢模塊QueryService queryService = new QueryService();//詢問廁所queryService.whereToilet();//...}
我們使用門面模式可以解決上述問題。首先,我們創(chuàng)建一個門面類——RestaurantFacade,
此類作為整個餐館功能入口。
public class RestaurantFacade {private OrderManager orderManager = new OrderManager();private QueryService queryService = new QueryService();//...public OrderManager orderService() {return orderManager;}public QueryService queryService() {return queryService;}//...
}
對于調(diào)用方來說,所有的功能我都通過RestaurantFacade一個類獲取,不關(guān)心也沒必要知道其內(nèi)部的實現(xiàn)和運(yùn)作方式。
不管該系統(tǒng)后續(xù)添加新功能還是刪除了舊功能,交互門面不變。
public static void main(String[] args) {//創(chuàng)建門面類RestaurantFacade facade = new RestaurantFacade();//下單facade.orderService().order("001");//結(jié)賬facade.orderService().bill("001", 350.00);//詢問廁所facade.queryService().whereToilet();//...}
在這里,為了進(jìn)一步方便管理,我們RestaurantFacade對外提供的功能是返回子模塊,然后子模塊再調(diào)用具體功能。這種通常是在業(yè)務(wù)十分龐大復(fù)雜的情況下采取的策略。你也可以直接對外提供具體的功能,而把模塊信息封裝在門面類內(nèi)部。
以點餐為例:
public class RestaurantFacade {private OrderManager orderManager = new OrderManager();//...public void order(String tableNo) {orderManager.order(tableNo);}//...
}
調(diào)用方代碼:
public static void main(String[] args) {//創(chuàng)建門面類RestaurantFacade facade = new RestaurantFacade();//下單facade.order("001");//...}
門面模式的好處
外觀模式是一種設(shè)計模式,旨在簡化復(fù)雜系統(tǒng)的接口,提供一個更簡單的接口來訪問系統(tǒng)的子系統(tǒng)集合。它通過將系統(tǒng)的復(fù)雜性隱藏在一個單一的接口背后,使得客戶端代碼更容易使用。以下是外觀模式的幾個好處:
-
簡化接口: 外觀模式提供了一個簡化的接口,使得客戶端不需要了解系統(tǒng)的復(fù)雜性和內(nèi)部工作原理,只需與外觀對象進(jìn)行交互即可。
-
降低耦合性: 外觀模式有助于降低系統(tǒng)中各個子系統(tǒng)之間的耦合度,因為客戶端只需與外觀對象交互,而不需要直接與子系統(tǒng)交互,從而減少了對子系統(tǒng)的依賴性。
-
隱藏實現(xiàn)細(xì)節(jié): 外觀模式將系統(tǒng)的內(nèi)部實現(xiàn)細(xì)節(jié)隱藏在外部,使得系統(tǒng)更易于維護(hù)和修改。如果系統(tǒng)的內(nèi)部實現(xiàn)發(fā)生變化,只需更新外觀類而不影響客戶端代碼。
-
提高易用性: 外觀模式使得客戶端代碼更易于理解和使用,因為它提供了一個簡單的接口來訪問復(fù)雜系統(tǒng)的功能,而無需了解系統(tǒng)的內(nèi)部復(fù)雜性。
-
促進(jìn)代碼組織和管理: 外觀模式可以幫助將系統(tǒng)分解為更小的模塊,并將這些模塊組織成更易于管理和維護(hù)的結(jié)構(gòu)。
總的來說,外觀模式通過簡化接口、降低耦合性、隱藏實現(xiàn)細(xì)節(jié)、提高易用性以及促進(jìn)代碼組織和管理等方面,可以幫助提高系統(tǒng)的可維護(hù)性、可擴(kuò)展性和可重用性。
門面模式源碼舉例
門面模式在第三方類庫中非常常見。例如Okhttp,我們使用它的功能,基本都是通過OkHttpClient這個類。
//創(chuàng)建門面對象,并進(jìn)行配置OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)//鏈接超時為2秒,單位為秒.writeTimeout(10, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS)//讀取超時.build();//執(zhí)行一個請求 okHttpClient.newCall(new Request.Builder().url("xxxx").build()).execute();