工廠模式:主要用來實例化有共同介面的類,工廠模式可以動態決定應該實例化那一個類別。
工廠模式的形態
工廠模式主要用一下幾種形態:
1:簡單工廠(Simple Factory)。
2:工廠方法(Factory Method)。
3:抽象工廠(Abstract Factory)。
簡單工廠(Simple Factory)
又叫靜態工廠,是工廠模式三中狀態中結構最為簡單的。主要有一個靜態方法,用來接受參數,並根據參數來決定傳回實現同一介面的不同類別的實例。讓我們來看一個具體的例子:
假設一家工廠,幾生產洗衣機,有生產冰箱,還有空調等等..
我們先為所有產品定義一個共同的產品介面
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 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類一出問題,系統就進入不能工作的狀態,這也是最為致命的一點....
以上的不足將在工廠模式的另外兩種狀態中得到解決。
工廠方法(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(); } }
從上面創建產品對象的代碼可以看出,工廠方法和簡單工廠的主要區別是,簡單工廠是把創建產品的職能都放在一個類別裡面,而工廠方法則把不同的產品放在實現了工廠介面的不同工廠類別裡面,這樣就算其中一個工廠類出了問題,其他工廠類也能正常運作,互相不受影響,以後增加新產品,也只需要新增一個實作工廠介面工廠類,就能達到,不用修改已有的程式碼。但工廠方法也有他限制的地方,那就是當面對的產品有複雜的等級結構的時候,例如,工廠除了生產家電外產品,還生產手機產品,這樣一來家電是手機就是兩大產品家族了,這兩大家族下麵包含了數量眾多的產品,每個產品又有多個型號,這樣就形成了一個複雜的產品樹了。如果用工廠方法來設計這個產品家族系統,就必須為每個型號的產品創建一個對應的工廠類,當有數百種甚至上千種產品的時候,也必須要有對應的上百成千個工廠類,這就出現了傳說的類爆炸,對於以後的維護來說,簡直就是一場災難.....
抽象工廠(Factory Method)
抽象工廠:意的意圖在於創建一系列相互關聯或互相依賴的對象。 <
我自己覺得抽象工廠是在工廠方法的基礎上引進了分類管理的概念....
工廠方法用來創建一個產品,它沒有分類的概念,而抽象工廠則用於創造一系列產品,所以產品分類成了抽象工廠的重點,
我們繼續用上面的例子來說明:
工廠生產的所有產品都用都用大寫字母來標明它們的型號,比如冰箱,就有“冰箱-A",「冰箱-B",同樣,其他的產品也都是遵守這個編號規則,於是就有了一下產品家族樹
冰箱:
冰箱-A
冰箱-B
洗衣機:
洗衣機-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的产品工厂 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(); } }
这样,我们的抽象工厂就完成了。有上面可以看出,在运用上我觉得工厂方法和抽象工厂,都有自己的应用场景,并没有什么优劣之分,但在应用抽象工厂之前,要先对创建的对象进行系统的分类,这点很重要,好的产品分类规则能为具体工厂类的选择调用和以后的扩展提供清晰的思路.
更多Java设计模式—工厂设计模式相关文章请关注PHP中文网!