模式動機與定義
模式動機
產品等級結構:產品等級結構即產品的繼承結構,例如一個抽象類是電視機,其子類有海爾電視機、海信電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是其子類。java
產品族:在抽象工廠模式中,產品族是指由同一個工廠生產的,位於不一樣產品等級結構中的一組產品,例如海爾電器工廠生產的海爾電視機、海爾電冰箱,海爾電視機位於電視機產品等級結構中,海爾電冰箱位於電冰箱產品等級結構中。
設計模式
模式定義
抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類。抽象工廠模式又稱爲Kit模式,屬於對象建立型模式。
dom
模式結構與分析
模式結構
抽象工廠模式包含以下角色:ide
AbstractFactory:抽象工廠ui
ConcreteFactory:具體工廠設計
AbstractProduct:抽象產品3d
ConcreteProduct:具體產品code
模式分析
模式實例與解析
模式實例
電器工廠:實例說明xml
一個電器工廠能夠生產多種類型的電器,如海爾工廠能夠生產海爾電視機、海爾空調等,TCL工廠能夠生產TCL電視機、TCL空調等,相同品牌的電器構成一個產品族,而相同類型的電器構成了一個產品等級結構,現使用抽象工廠模式模擬該場景。對象
電器工廠:參考類圖
電器工廠:參考代碼
代碼結構
Television接口
package abstractfactory; public interface Television { public void play(); }
HaierTelevision類
package abstractfactory; public class HaierTelevision implements Television { @Override public void play() { System.out.println("海爾電視機播放中···"); } }
TCLTelevision類
package abstractfactory; public class TCLTelevision implements Television { @Override public void play() { System.out.println("TCL電視機播放中···"); } }
AirConditioner接口
package abstractfactory; public interface AirConditioner { public void changeTemperature(); }
HaierAirConditioner類
package abstractfactory; public class HaierAirConditioner implements AirConditioner { @Override public void changeTemperature() { System.out.println("海爾空調溫度改變中···"); } }
TCLAirConditioner類
package abstractfactory; public class TCLAirConditioner implements AirConditioner { @Override public void changeTemperature() { System.out.println("TCL空調溫度改變中···"); } }
EFactory接口
package abstractfactory; public interface EFactory { public Television produceTelevision(); public AirConditioner produceAirConditioner(); }
HaierFactory類
package abstractfactory; public class HaierFactory implements EFactory { @Override public Television produceTelevision() { return new HaierTelevision(); } @Override public AirConditioner produceAirConditioner() { return new HaierAirConditioner(); } }
TCLFactory類
package abstractfactory; public class TCLFactory implements EFactory { @Override public Television produceTelevision() { return new TCLTelevision(); } @Override public AirConditioner produceAirConditioner() { return new TCLAirConditioner(); } }
AbstractFactoryconfig.xml
<?xml version="1.0" encoding="UTF-8"?> <config> <className>abstractfactory.HaierFactory</className> </config>
XMLUtil類
package abstractfactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; public class XMLUtil { //該方法用於從XML配置文件中提取具體類類名,並返回一個實例對象 public static Object getBean(){ try { //建立文檔對象 DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File("D:\\MyNewWorld\\Study_JAVA\\MyHome\\Write_java\\My_Maven\\src\\main\\resources\\AbstractFactoryconfig.xml")); //獲取包含類名的文本節點 NodeList n1 = doc.getElementsByTagName("className"); Node classNode = n1.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; } } }
Client類
package abstractfactory; public class Client { public static void main(String[] args) { try{ EFactory factory; Television tv; AirConditioner ac; factory = (EFactory) XMLUtil.getBean(); tv = factory.produceTelevision(); tv.play(); ac = factory.produceAirConditioner(); ac.changeTemperature(); }catch (Exception e){ System.out.println(e.getMessage()); } } }
運行結果
模式效果與應用
抽象工廠模式優勢:
隔離了具體類的生成,使得客戶端並不須要知道什麼被建立
當一個產品族中的多個對象被設計成一塊兒工做時,它可以保證客戶端始終只使用同一個產品族中的對象
增長新的產品族很方便,無需修改已有系統,符合開閉原則
抽象工廠模式缺點:
增長新的產品等級結構麻煩,須要對原有系統進行較大的修改,甚至須要修改抽象層代碼,這顯然會帶來較大的不便,違背了開閉原則。
在如下狀況下能夠使用抽象工廠模式:
一個系統不該當依賴於產品類實例如何被建立、組合和表達的細節
系統中有多於一個的產品族,但每次只使用其中某一產品族
屬於同一個產品族的產品將在一塊兒使用,這一約束必須在系統的設計中體現出來。
產品等級結構穩定,在設計完成以後不會向系統中增長新的產品等級結構或者刪除已有的產品等級結構。
往期推薦
《【一】、設計模式概述》
《【二】、UML基礎知識》
《【三】、面向對象設計原則》
《【四】、簡單工廠模式》
《【五】、工廠方法模式》