定義:java
抽象工廠模式(Abstract Factory Pattern)是一種比較經常使用的模式,其定義以下:編輯器
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.(爲建立一組相關或相互依賴的對象提供一個接口,並且無須指定它們的具體類。)ide
抽象工廠模式的通用類圖以下所示:操作系統
抽象工廠模式是工廠方法模式的升級版本,在有多個業務品種、業務分類時,經過抽象工廠模式產生須要的對象是一種很是好的解決方式。咱們來看看抽象工廠的通用源代碼,首先有兩個互相影響的產品線(也叫作產品族),例如製造汽車的左側門和右側門,這兩個應該是數量相等的——兩個對象之間的約束,每一個型號的車門都是不同的,這是產品等級結構約束的,咱們先看看兩個產品族的類圖,設計
注意類圖上的圈圈、框框相對應,兩個抽象的產品類能夠有關係,例如共同繼承或實現一個抽象類或接口,其源代碼以下所示code
public abstract class AbstractProductA { //每一個產品共有的方法 public void shareMethod(){ } //每一個產品相同方法,不一樣實現 public abstract void doSomething(); } }
兩個具體的產品實現類以下:對象
public class ProductA1 extends AbstractProductA { public void doSomething() { System.out.println("產品A1的實現方法"); } } public class ProductA2 extends AbstractProductA { public void doSomething() { System.out.println("產品A2的實現方法"); } }
產品B與此相似,再也不贅述。抽象工廠類AbstractCreator的職責是定義每一個工廠要實現的功能,在通用代碼中,抽象工廠類定義了兩個產品族的產品建立,如:繼承
public abstract class AbstractCreator { //建立A產品家族 public abstract AbstractProductA createProductA(); //建立B產品家族 public abstract AbstractProductB createProductB(); }
注意 有N個產品族,在抽象工廠類中就應該有N個建立方法。接口
如何建立一個產品,則是由具體的實現類來完成的,Creator1和Creator2如:圖片
public class Creator1 extends AbstractCreator { //只生產產品等級爲1的A產品 public AbstractProductA createProductA() { return new ProductA1(); } //只生產產品等級爲1的B產品 public AbstractProductB createProductB() { return new ProductB1(); } } public class Creator2 extends AbstractCreator { //只生產產品等級爲2的A產品 public AbstractProductA createProductA() { return new ProductA2(); } //只生產產品等級爲2的B產品 public AbstractProductB createProductB() { return new ProductB2(); } }
注意 有M個產品等級就應該有M個實現工廠類,在每一個實現工廠中,實現不一樣產品族的生產任務。
在具體的業務中如何產生一個與實現無關的對象呢?以下所示:
public class Client { public static void main(String[] args) { //定義出兩個工廠 AbstractCreator creator1 = new Creator1(); AbstractCreator creator2 = new Creator2(); //產生A1對象 AbstractProductA a1 = creator1.createProductA(); //產生A2對象 AbstractProductA a2 = creator2.createProductA(); //產生B1對象 AbstractProductB b1 = creator1.createProductB(); //產生B2對象 AbstractProductB b2 = creator2.createProductB(); /* * 而後在這裏就能夠隨心所欲了... */ } }
在場景類中,沒有任何一個方法與實現類有關係,對於一個產品來講,咱們只要知道它的工廠方法就能夠直接產生一個產品對象,無須關心它的實現類。
抽象工廠模式的應用
抽象工廠模式的優勢:
封裝性,每一個產品的實現類不是高層模塊要關心的,它要關心的是什麼?是接口,是抽象,它不關心對象是如何建立出來,這由誰負責呢?工廠類,只要知道工廠類是誰,我就能建立出一個須要的對象,省時省力,優秀設計就應該如此。
產品族內的約束爲非公開狀態。
抽象工廠模式的缺點:
抽象工廠模式的最大缺點就是產品族擴展很是困難,爲何這麼說呢?咱們以通用代碼爲例,若是要增長一個產品C,也就是說產品家族由原來的2個增長到3個,看看咱們的程序有多大改動吧!抽象類AbstractCreator要增長一個方法createProductC(),而後兩個實現類都要修改,想一想看,這嚴重違反了開閉原則,並且咱們一直說明抽象類和接口是一個契約。改變契約,全部與契約有關係的代碼都要修改,那麼這段代碼叫什麼?叫「有毒代碼」,——只要與這段代碼有關係,就可能產生侵害的危險!
抽象工廠模式的使用場景
抽象工廠模式的使用場景定義很是簡單:一個對象族(或是一組沒有任何關係的對象)都有相同的約束,則可使用抽象工廠模式。什麼意思呢?例如一個文本編輯器和一個圖片處理器,都是軟件實體,可是*nix下的文本編輯器和Windows下的文本編輯器雖然功能和界面都相同,可是代碼實現是不一樣的,圖片處理器也有相似狀況。也就是具備了共同的約束條件:操做系統類型。因而咱們可使用抽象工廠模式,產生不一樣操做系統下的編輯器和圖片處理器。
抽象工廠模式的注意事項
在抽象工廠模式的缺點中,咱們提到抽象工廠模式的產品族擴展比較困難,可是必定要清楚,是產品族擴展困難,而不是產品等級。在該模式下,產品等級是很是容易擴展的,增長一個產品等級,只要增長一個工廠類負責新增長出來的產品生產任務便可。也就是說橫向擴展容易,縱向擴展困難。
最佳實踐
抽象工廠模式是一個簡單的模式,使用的場景很是多,你們在軟件產品開發過程當中,涉及不一樣操做系統的時候,均可以考慮使用抽象工廠模式,例如一個應用,須要在三個不一樣平臺(Windows、Linux、Android)上運行,你會怎麼設計?分別設計三套不一樣的應用?非也,經過抽象工廠模式屏蔽掉操做系統對應用的影響。三個不一樣操做系統上的軟件功能、應用邏輯、UI都應該是很是相似的,惟一不一樣的是調用不一樣的工廠方法,由不一樣的產品類去處理與操做系統交互的信息。