1. 程式人生 > 其它 >Java設計模式——工廠模式

Java設計模式——工廠模式

一、工廠模式的形態

概念:工廠模式:主要用來例項化有共同介面的類,工廠模式可以動態決定應該例項化那一個類

工廠模式主要用一下幾種形態:

  • 簡單工廠(Simple Factory)
  • 工廠方法(Factory Method)
  • 抽象工廠(Abstract Factory)

二、簡單工廠(Simple Factory)

又叫靜態工廠,是工廠模式三中狀態中結構最為簡單的。主要有一個靜態方法,用來接受引數,並根據引數來決定

返回實現同一介面的不同類的例項。我們來看一個具體的例子:

假設一家工廠,幾生產洗衣機,有生產冰箱,還有空調等等..

我們先為所有產品定義一個共同的產品介面

Product.java

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)

上面的程式碼告訴我們,簡單工廠並不簡單,它是整個模式的核心,一旦他出了問題,整個模式都將受影響而不能工

作,為了降低風險和為日後的維護、擴充套件做準備,我們需要對它進行重構,引入工廠方法。

工廠方法為工廠類定義了介面,用多型來削弱了工廠類的職能,以下是工廠介面的定義:

Factory.java

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",同樣,其他的產品

也都是遵守這個編號規則,於是就有了一下產品家族樹

冰箱:

  1. 冰箱-A
  2. 冰箱-B

洗衣機:

  1. 洗衣機-A
  2. 洗衣機-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(); 
       } 
} 

這樣,我們的抽象工廠就完成了。有上面可以看出,在運用上我覺得工廠方法和抽象工廠,都有自己的應用場景,

並沒有什麼優劣之分,但在應用抽象工廠之前,要先對建立的物件進行系統的分類,這點很重要,好的產品分類規

則能為具體工廠類的選擇呼叫和以後的擴充套件提供清晰的思路.