六個建立型模式之抽象工廠模式
阿新 • • 發佈:2020-10-12
工廠三兄弟:簡單工廠模式,工廠方法模式,抽象工廠模式我選最優講解,以後其他的設計模式都選用改良版最優模式講解,其他的請自行百度。
工廠方法模式通過引入工廠等級結構,解決了簡單工廠模式中工廠類職責太重的問題,但由於工廠方法模式中的每個工廠只生產一類產品,可能會導致系統中存在大量的工廠類,勢必會增加系統的開銷。此時,我們可以考慮將一些相關的產品組成一個“產品族”,由同一個工廠來統一生產,這就是我們本文將要學習的抽象工廠模式的基本思想。 介面面板庫的初始設計(案例) Sunny軟體公司欲開發一套介面面板庫,可以對Java桌面軟體進行介面美化。為了保護版權,該面板庫原始碼不打算公開,而只向用戶提供已打包為jar檔案的class位元組碼檔案。使用者在使用時可以通過選單來選擇面板,不同的面板將提供視覺效果不同的按鈕、文字框、組合框等介面元素,其結構示意圖如圖所示:完整解決方案:
Sunny公司開發人員使用抽象工廠模式來重構介面面板庫的設計,其基本結構如圖所示:
介面面板庫結構圖:
在圖中,SkinFactory介面充當抽象工廠,其子類SpringSkinFactory和SummerSkinFactory充當具體工廠,介面Button、TextField和ComboBox充當抽象產品,其子類SpringButton、SpringTextField、SpringComboBox和SummerButton、SummerTextField、SummerComboBox充當具體產品。完整程式碼如下所示:
按鈕:
//在本例項中我們對程式碼進行了大量簡化,實際使用時,介面元件的初始化程式碼較為複雜//按鈕介面:抽象產品 interface Button { public void display(); }
//Spring按鈕類:具體產品 class SpringButton implements Button { public void display() { System.out.println("顯示淺綠色按鈕。"); } }
//Summer按鈕類:具體產品 class SummerButton implements Button { public void display() { System.out.println("顯示淺藍色按鈕。"); } }
文字框:
//文字框介面:抽象產品 interface TextField { public void display(); }
//Spring文字框類:具體產品 class SpringTextField implements TextField { public void display() { System.out.println("顯示綠色邊框文字框。"); } }
//Summer文字框類:具體產品 class SummerTextField implements TextField { public void display() { System.out.println("顯示藍色邊框文字框。"); } }
組合框:
//組合框介面:抽象產品 interface ComboBox { public void display(); }
//Spring組合框類:具體產品 class SpringComboBox implements ComboBox { public void display() { System.out.println("顯示綠色邊框組合框。"); } }
//Summer組合框類:具體產品 class SummerComboBox implements ComboBox { public void display() { System.out.println("顯示藍色邊框組合框。"); } }
開始建立介面面板工廠:
//介面面板工廠介面:抽象工廠 interface SkinFactory { public Button createButton(); public TextField createTextField(); public ComboBox createComboBox(); }
//Spring面板工廠:具體工廠 class SpringSkinFactory implements SkinFactory { public Button createButton() { return new SpringButton(); } public TextField createTextField() { return new SpringTextField(); } public ComboBox createComboBox() { return new SpringComboBox(); } }
//Summer面板工廠:具體工廠 class SummerSkinFactory implements SkinFactory { public Button createButton() { return new SummerButton(); } public TextField createTextField() { return new SummerTextField(); } public ComboBox createComboBox() { return new SummerComboBox(); } }
為了讓系統具備良好的靈活性和可擴充套件性,我們引入了工具類XMLUtil和配置檔案,
XMLUtil類的程式碼如下所示:
import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.SAXException; import java.io.*; public class XMLUtil { //該方法用於從XML配置檔案中提取具體類類名,並返回一個例項物件 public static Object getBean() { try { //建立文件物件 DocumentBuilderFactory dFactory = DocumentBuilderFactory DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File("config.xml")); //獲取包含類名的文字節點 NodeList nl = doc.getElementsByTagName("className"); Node classNode = nl.item(0).getFirstChild(); String cName = classNode.getNodeValue(); //通過類名生成例項物件並將其返回 Class c = Class.forName(cName); Object obj = c.newInstance(); return obj; } catch (Exception e) { e.printStackTrace(); return null; } } }
配置檔案config.xml中儲存了具體工廠類的類名,程式碼如下所示:
<?xml version="1.0"?> <config> <className>SpringSkinFactory</className> </config>
編寫如下客戶端測試程式碼:
class Client { public static void main(String args[]) { //使用抽象層定義SkinFactory factory; Button bt; TextField tf; ComboBox cb; factory = (SkinFactory)XMLUtil.getBean(); bt = factory.createButton(); tf = factory.createTextField(); cb = factory.createComboBox();
bt.display(); tf.display(); cb.display(); } }
編譯並執行程式,輸出結果如下:
顯示淺綠色按鈕。
顯示綠色邊框文字框。
顯示綠色邊框組合框。
如果需要更換面板,只需修改配置檔案即可,在實際環境中,我們可以提供視覺化介面,例如選單或者視窗來修改配置檔案,使用者無須直接修改配置檔案。如果需要增加新的面板,只需增加一族新的具體元件並對應提供一個新的具體工廠,修改配置檔案即可使用新的面板, 原有程式碼無須修改,符合“開閉原則”。