工廠模式:主要用來實例化有共同接口的類,工廠模式可以動態決定應該實例化那一個類。
工廠模式主要用以下幾種形態: 簡單工廠(Simple Factory), 工廠方法(Factory Method), 抽象工廠(Abstract Factory)
?
1. 簡單工廠模式 ( Simple Factory )
??????? 簡單工廠又叫 靜態工廠 ,是工廠模式三中狀態中結構最為簡單的它主要有一個靜態方法,用來接受參數,并根據參數來決定返回實現同一接口的不同類的實例。
??????? 我們來看一個具體的例子:假設一家工廠,幾生產洗衣機,有生產冰箱,還有空調等等。我們先為所有產品定義一個共同的產品接口如下:
public interface Product{}
? ?????? 接著我們讓這個工廠的所有產品都必須實現此接口,其Java代碼如下:
public class Washer implements Product { public Washer() { System.out.println("制造了一臺洗衣機."); } } public class Icebox implements Product { public Icebox() { System.out.println("制造了一臺冰箱."); } } public class AirCondition implements Product { public Icebox() { System.out.println("制造了一臺空調."); } }
?
?????? 接下來我們來寫一個工廠類,由它來負責生產以上的產品,其Java代碼如下:
public class SimpleFactory { public static Product factory(String productName) throws Exception { if(productName.equals("Washer")) { return new Washer(); } else if(productName.equals("Icebox")) { return new Icebox(); } else if(productName.equals("AirCondition")) { return new AirCondition(); } else { throw new Exception("暫時無法生產該商品."); } } }
??????? 有了這個工廠類,我們就可以開始下定單了, SimpleFactory 將根據不同的定單類決定生產什么產品。
public static void main(String[] args) { ??????? try ??????? { ??????? ??????? SimpleFactory.factory("Washer"); ??????? ??????? SimpleFactory.factory("Icebox"); ??????? ??????? SimpleFactory.factory("AirCondition"); ??????? } ??????? catch (Exception e) ??????? { ??????? ??????? e.printStackTrace(); ??????? } }
??????? 由上面的代碼可以看出,簡單工廠的核心就是一個 SimpleFactory 類,他擁有必要的邏輯判斷能力和所有產品的創建權利,我們只需要向把定單給他,就能得到我們想要的產品。這使用起來似乎非常方便。但實際上,這個 SimpleFactory 有很多的局限。
??????? 首先,我們每次想要增加一種新產品的時候,都必須修改 SimpleFactory 的原代碼。
??????? 其次,當我們擁有很多很多產品的時候,而且產品之間又存在復雜的層次關系的時候,這個類必須擁有復雜的邏輯判斷能力,其代碼量也將不斷地激增,這對以后的維護簡直就是恐怖兩個字...
??????? 還有就是,整個系統都嚴重依賴
SimpleFactory
類,只要
SimpleFactory
類一出問題,系統就進入不能工作的狀態,這也是最為致命的一點....
??????? 以上的不足將在工廠模式的另外兩種狀態中得到解決。
?
2. 工廠方法 ( Factory Method )
??????? 上面的代碼告訴我們,
簡單工廠
并不簡單,它是整個模式的核心,一旦他出了問題,整個模式都將受影響而不能工作,為了降低風險和為日后的維護、擴展做準備,我們需要對它進行重構,引入
工廠方法
。
??????? 工廠方法為工廠類定義了接口,用多態來削弱了工廠類的職能,以下是工廠接口的定義:
public interface Factory { ??????? public Product create(); }
?????? 我們再來定義一個產品接口:
public interface Product { }
?????? 以下是實現了產品接口的產品類:
public class Washer implements Product { public Washer() { System.out.println("制造了一臺洗衣機."); } } public class Icebox implements Product { public Icebox() { System.out.println("制造了一臺冰箱."); } } public class AirCondition implements Product { public Icebox() { System.out.println("制造了一臺空調."); } }
? ? ? ? 接下來,就是工廠方法的核心部分,也就是具體創建產品對象的具體工廠類:
//創建洗衣機的工廠 public class CreateWasher implements Factory { ??????? public Product create() ??????? { ??????? ??????? return new Washer(); ??????? } } //創建冰箱的工廠 public class CreateIcebox implements Factory { ??????? public Product create() ??????? { ??????? ??????? return new Icebox(); ??????? } } //創建空調的工廠 public class CreateAirCondition implements Factory { ??????? public Product create() ??????? { ??????? ??????? return new AirCondition(); ??????? } }
?
???????? 從上面創建產品對象的代碼可以看出, 工廠方法 和 簡單工廠 的主要區別是, 簡單工廠 是把創建產品的職能都放在一個類里面,而 工廠方法 則把不同的產品放在實現了工廠接口的不同工廠類里面,這樣就算其中一個工廠類出了問題,其他工廠類也能正常工作,互相不受影響,以后增加新產品,也只需要新增一個實現工廠接口工廠類,就能達到,不用修改已有的代碼。但 工廠方法 也有他局限的地方,那就是當面對的產品有復雜的等級結構的時候,例如,工廠除了生產家電外產品,還生產手機產品,這樣一來家電是手機就是兩大產品家族了,這兩大家族下面包含了數量眾多的產品,每個產品又有多個型號,這樣就形成了一個復雜的產品樹了。如果用 工廠方法 來設計這個產品家族系統,就必須為每個型號的產品創建一個對應的工廠類,當有數百種甚至上千種產品的時候,也必須要有對應的上百成千個工廠類,這就出現了傳說的類爆炸,對于以后的維護來說,簡直就是一場災難.....
?
三. 抽象工廠(Abstract Factory)
??????? 抽象工廠
:意的意圖在于創建一系列互相關聯或互相依賴的對象。<<Java設計模式>>
???????
抽象工廠
是在
工廠方法
的基礎上引進了分類管理的概念。工廠方法用來創建一個產品,它沒有分類的概念,而抽象工廠則用于創建一系列產品,所以產品分類成了抽象工廠的重點。
??????? 我們繼續用上面的例子來說明:工廠生產的所有產品都用都用大寫字母來標明它們的型號,比如冰箱,就有“冰箱-A",“冰箱-B"。同樣,其他的產品也都是遵守這個編號規則,于是就有了一下產品家族樹:
產品樹
?? ? ??????? |
?? ? ??????? |
|
?
??????? 我們可以為冰箱和洗衣機分別定義兩個產品接口,以對他們進行分類:
//洗衣機接口 public interface Washer {} //冰箱接口 public interface Icebox {}
? ? ? ?? 接著,我們分別創建這兩個接口的具體產品:
//洗衣機-A public class WasherA implements Washer { ??????? public WasherA() ??????? { ??????? ??????? System.out.println("制造了一臺洗衣機-A"); ??????? } } //洗衣機-B public class WasherB implements Washer { ??????? public WasherB() ??????? { ??????? ??????? System.out.println("制造了一臺洗衣機-B"); ??????? } } //冰箱-A public class IceboxA implements Icebox { ??????? public IceboxA() ??????? { ??????? ??????? System.out.println("制造了一臺冰箱-A"); ??????? } } //冰箱-B public class IceboxB implements Icebox { ??????? public IceboxB() ??????? { ??????? System.out.println("制造了一臺冰箱-B"); ??????? } }
? ? ? ? 到此,產品部分我們準備好了,接下來我們來處理工廠部分,我們先來定義工廠行為接口:
public interface Factory { ??????? public Washer createWasher(); ??????? public Icebox createIcebox(); }
??????? 接下來我創造具體的工廠類,我們根據上面產品的接口,把型號A的產品分為一類,由一個工廠來管理,把型號為B的產品有另一個工廠管理,根據這個分類,我們可以實現如下的兩個具體工廠類:
//創建型號為A的產品工廠 public class FactoryA implements Factory {??????? ??????? //創建洗衣機-A ??????? public Washer createWasher() ??????? { ??????? ??????? return new WasherA(); ??????? } ??????? //創建冰箱-A ??????? public Icebox createIcebox() ??????? { ??????? ??????? return new IceboxA(); ??????? } } //創建型號為B的產品工廠 public class FactoryB implements Factory { ??????? //創建洗衣機-B ??????? public Washer createWasher() ??????? { ??????? ??????? return new WasherB(); ??????? } ??????? //創建冰箱-B ??????? public Icebox createIcebox() ??????? { ??????? ??????? return new IceboxB(); ??????? } }
? ? ?? 這樣,我們的抽象工廠就完成了。有上面可以看出,在運用上我覺得工廠方法和抽象工廠,都有自己的應用場景,并沒有什么優劣之分,但在應用抽象工廠之前,要先對創建的對象進行系統的分類,這點很重要,好的產品分類規則能為具體工廠類的選擇調用和以后的擴展提供清晰的思路。
?
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
