抽象工廠模式是常見的建造型設計模式之一,比工廠方法模式抽象程度更高,工廠方法模式中具體工廠只生產一種具體產品,但在抽象工廠模式中,具體工廠可以生產相關的一組具體產品,這樣一組產品稱為產品族,產品族中的每一個產品分屬于某一產品繼承等級結構,
模式動機
有時候我們需要一個工廠提供多個產品物件,而不是單一一個產品物件,如一個電器設備工廠,它可以生產電視機、電冰箱、空調等設備,而不只是生成某種型別的電器,為了更清晰地理解抽象工廠模式,這里先引入兩個概念:
-
產品等級結構:產品等級結構即產品的繼承結構,如一個抽象類是電視機,其子類有海爾電視機、TCL電視機等,抽象電視機與具體品牌電視機之間構成了一個產品等級結構,
-
產品族:指由同一工廠生產的,位于不同產品等級結構中的一組產品,如海爾電器工廠生產海爾電視機、海爾電冰箱,則它們是同一產品族,各自位于不同產品等級結構,

當系統提供的工廠生產的具體產品不是一個簡單物件,而是多個位于不同產品等級結構中屬于不同型別的具體產品時需要使用抽象工廠模式,
模式定義
提供一個創建一系列相關或相互依賴物件的介面,而無須指定它們具體的類,
模式結構
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dhyAERw4-1583586756776)(C:\Users\LENOVO\AppData\Roaming\Typora\typora-user-images\image-20200307160832169.png)]](https://img-blog.csdnimg.cn/20200307211301896.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0NTRE5faGFuZHNvbWU=,size_16,color_FFFFFF,t_70)
-
AbstractFacory(抽象工廠)
抽象工廠用于宣告生產抽象產品的方法,在一個抽象工廠中可以定義一組方法,每一方法對應一個產品等級結構
-
ConcreteFactory(具體工廠)
具體工廠實作抽象工廠宣告的生產抽象產品的方法,生產一組具體產品,這些產品構成一個產品族,每一個產品都位于某個產品等級結構中,
-
AbstractProduct(抽象產品)
抽象產品為每種產品宣告介面,在抽象產品中定義產品的抽象業務方法
-
ConcreteProduct(具體產品)
具體產品定義具體工廠生產的具體產品物件,實作抽象產品介面中定義的業務方法,
抽象工廠模式實體之電器工廠
-
實體說明
一個電器工廠可以產生多種型別的電器,如海爾工廠可以生產海爾電視機、海爾空調等,TCL工廠可以生產TCL電視機、TCL空調等,相同品牌的電器構成一個產品族,而相同型別電器構成一個產品等級結構,
-
實體代碼及解釋

-
抽象產品類Television
public interface Television { void play(); } -
具體產品類HairTelevision(海爾電視機類)
public class HairTelevision implements Television { @Override public void play() { System.out.println("海爾電視機播放中......"); } } -
具體產品類TCLTelevision(TCL電視機類)
public class TCLTelevision implements Television { @Override public void play() { System.out.println("TCL電視機播放中......."); } } -
抽象產品類AirConditioner
public interface AirConditioner { void changeTemperature(); } -
具體產品類HairAirConditioner(海爾空調類)
public class HairAirConditioner implements AirConditioner { @Override public void changeTemperature() { System.out.println("海爾空調溫度改變中....."); } } -
具體產品類TCLAirConditioner(TCL空調類)
public class TCLAirConditioner implements AirConditioner { @Override public void changeTemperature() { System.out.println("TCL空調溫度改變中......"); } } -
抽象工廠類EFactory
public interface EFactory { Television produceTelevision(); AirConditioner produceAirConditioner(); } -
具體工廠類HairFactory(海爾工廠類)
public class HairFactory implements EFactory { @Override public Television produceTelevision() { return new HairTelevision(); } @Override public AirConditioner produceAirConditioner() { return new HairAirConditioner(); } } -
具體工廠類TCLPFactory
public class TCLFactory implements EFactory { @Override public Television produceTelevision() { return new TCLTelevision(); } @Override public AirConditioner produceAirConditioner() { return new TCLAirConditioner(); } } -
XML操作工具類
public class XMLUtil { public static Object getBean() throws Exception { //創建決議器工廠 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //創建決議器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //得到document Document document = builder.parse("configPhone.xml"); //獲取包含品牌名稱的文本節點 NodeList brandNameList = document.getElementsByTagName("factoryName"); Node classNode = brandNameList.item(0).getFirstChild(); String factoryName = classNode.getNodeValue().trim(); // System.out.println(factoryName); Class c = Class.forName(factoryName); Object o = c.newInstance(); return o; } } -
組態檔
<?xml version="1.0" encoding="UTF-8" ?> <configuration> <factoryName>HairFactory</factoryName> </configuration> -
測驗類
public class Test { public static void main(String[] args) throws Exception { EFactory factory = (EFactory) XMLUtil.getBean(); Television television = factory.produceTelevision(); television.play(); AirConditioner airConditioner = factory.produceAirConditioner(); airConditioner.changeTemperature(); } } -
結果分析
如果在組態檔將節點中內容設定為 HairFactory,則輸出結果如下:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tPoxjd7a-1583586756777)(C:\Users\LENOVO\AppData\Roaming\Typora\typora-user-images\image-20200307174255434.png)]](https://img.uj5u.com/2020/09/19/86613191949323.png)
如果在組態檔將節點中內容設定為 TCLFactory,則輸出結果如下:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-fZc1As2U-1583586756779)(C:\Users\LENOVO\AppData\Roaming\Typora\typora-user-images\image-20200307174351784.png)]](https://img.uj5u.com/2020/09/19/86613191949324.png)
如果需要增加新品牌的電器,即增加一個新的產品族,如增加海信電視機和海信空調,則只需對應增加一個具體工廠,再將組態檔中具體工廠類名修改為新增工廠類名,原有代碼無須修改,但如果要增加新的產品,如增加新的電器產品洗衣機,抽象工廠需要宣告一個生產洗衣機的方法,所有具體工廠類都需實作該方法,將導致系統不再符合開閉原則,
-
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/83452.html
標籤:其他
上一篇:HTTP協議詳解(深入理解)
