標籤:完成 執行 customer 屏蔽 移植 調用 設計 control pre
前言
這次要介紹的是面板模式(也稱為門面模式),面板模式也屬於結構型模式,其實面板模式還是非常好理解的,簡單的來講就是將多個複雜的業務封裝成一個方法,在調用此方法時可以不必關係具體執行了哪些業務,而只關心結果即可。這個情境其實在日常開發中使用的頻率還是非常高的,下面來簡單瞭解一下吧。
面板模式概念介紹
面板模式是隱藏了系統的複雜性,能夠為子系統中的一組介面提供一個統一的介面。客戶在使用系統時不必和子系統打交道了,降低了客戶和子系統間的耦合。
舉例
喝茶問題,當紀大煙袋跟和二想喝茶了,這個時候他們就會自己動手,拿茶具,開水,茶葉然後就把茶泡了。過程如。
這樣兩個人都要自己操作茶具,開水,茶葉等,但是其實他倆就是想喝茶,才不關心茶是怎麼泡出來的。所以這個時候他們倆就去茶館了,這樣也不用自己動手泡茶了,直接告訴茶館的店小二兒就行了。此時過程就變成了下面這樣的了。
下面用代碼來實現一下這個過程:
先獲得飲用水
public class DrinkableWater { public DrinkableWater(){ System.out.println("可飲用水準備好了"); } //煮水 public void facadeWater(){ System.out.println("可飲用水沸騰了"); }}
再獲得茶葉
public class Tea { public Tea(){ System.out.println("茶葉準備好了。"); } //取茶 public void facadeTea(){ System.out.println("可以泡茶了。"); }}
然後獲得茶杯就可以泡茶了。
public class TeaCup { public TeaCup(){ System.out.println("茶杯準備好了"); } //泡茶 public void facadeTeaCup(Tea tea){ tea.facadeTea(); System.out.println("茶葉泡進茶杯了。"); System.out.println("等了一會兒,一杯又香又濃的茶沖好了。"); }}
店小二泡茶
public class Waiter { private DrinkableWater drinkableWater = new DrinkableWater(); private TeaCup teaCup = new TeaCup(); private Tea tea = new Tea(); //獲得一杯茶 public void getTea(){ drinkableWater.facadeWater(); teaCup.facadeTeaCup(tea); }}
顧客來喝茶了
public class Customer { public static void main(String[] args) { //叫店小二 Waiter waiter = new Waiter(); //從店小二那獲得一杯茶 waiter.getTea(); }}
運行結果
可飲用水準備好了茶杯準備好了茶葉準備好了。可飲用水沸騰了可以泡茶了。茶葉泡進茶杯了。等了一會兒,一杯又香又濃的茶沖好了。
面板模式的結構
面板模式的抽象結構圖如下:
在面板模式中主要包含如下幾個角色。
1、門面角色(facade):這是面板模式的核心。它被客戶角色調用,因此它熟悉子系統的功能。它內部根據客戶角色已有的需求預定了幾種功能組合。
2、子系統角色(SystemA、SystemB、SystemC):實現了子系統的功能。對子系統角色來說,facade角色與客戶角色一樣,是未知的,它沒有任何facade角色的資訊和連結。
3、客戶角色(client):調用facade角色來完成要得到的功能。
在上面的泡茶的例子中,和二和紀大煙袋就是客戶角色,茶館店小二兒就是門面角色,茶具、飲用水、茶葉就是子系統角色。
面板模式的優點
1、對用戶端屏蔽了子系統組件,減少了用戶端處理的對象數量,也減少了用戶端的代碼量。
2、實現了用戶端和子系統的鬆散耦合,使得子系統個變化不會影響到調用它的用戶端,只需要改變外觀類即可。
3、一個子系統的變化不會影響到另一個子系統,子系統內部變化也不會影響到外觀對象。
面板模式的缺點
1、不能很好地限制用戶端直接使用子系統類,如果對用戶端訪問子系統類做太多的限制則減少了可變性和靈活性。
2、如果設計不當,增加新的子系統可能需要修改外觀類的原始碼,違背了開閉原則。
適用情境
當要為訪問一系列複雜的子系統提供一個簡單入口時可以使用面板模式。
用戶端程式與多個子系統之間存在很大的依賴性。引入外觀類可以將子系統與用戶端解耦,從而提高子系統的獨立性和可移植性。
在層次化結構中,可以使用面板模式定義系統中每一層的入口,層與層之間不直接產生聯絡,而通過外觀類建立聯絡,降低層之間的耦合度。
延伸
在上面的例子中,我們定義的門面是一個具體的類,但是當需要增加新的功能的時候,就需要修改門面類了,所以最好的辦法是做成抽象門面,也就是將門面類的功能抽象出來,然後又不同的需求的時候,可以做兩個具體的門面類。例如:紀大煙袋跟和二去茶館喝茶是一個門面類,去上街買東西又是另一個門面類。
想瞭解更多的設計模式請查看Java設計模式學習記錄-GoF設計模式概述。
我不慌,世界就不慌。加油吧!
Java設計模式學習記錄-面板模式