簡單工廠模式&工廠方法模式&抽象工廠模式的區別

 以前寫過一篇關於工廠模式(Factory Pattern)的隨筆,裏面分析了簡單工廠模式,但對於工廠方法和抽象工廠的分析較爲簡略。這裏從新分析分析三者的區別,工廠模式是java設計模式中比較簡單的一個設計模式,但不少地方都用到了工廠模式,(如解析xml中,jdbc鏈接數據庫等)利用好工廠模式對程序的設計頗有用處。工廠模式在一些設計模式的書中分爲簡單工廠模式,工廠方法模式和抽象工廠模式三類。也有把工廠方法模式劃分到抽象工廠模式的,認爲工廠方法是抽象工廠模式的特例的一種,就是隻有一個要實現的產品接口。下面結合例子分析三者的區別。java

  首先是簡單工廠模式,這裏以工廠生產產品爲例。數據庫

產品類的共同接口設計模式

1 1 package factory;
2 2 /**
3 3  * 
4 4  * @author CIACs
5 5  *
6 6  */
7 7 public interface Product {
8 8     //聲明類所需繼承的共同接口,也能夠是抽象類
9 9 }

產品Aide

 1 package factory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class ProductA implements Product {
 8     public ProductA() {
 9         System.out.println("ProductA");
10     }
11 }

產品Bpost

 1 package factory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class ProductB implements Product {
 8     public ProductB() {
 9         System.out.println("ProductB");
10     }
11 }

工廠類spa

 1 package factory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class Factory {
 8     //能夠在工廠類中添加任何你所須要的邏輯
 9     public static Product create(String str)
10     {
11         //生成ProductA
12         if(str.equalsIgnoreCase("ProductA"))
13         {
14             return new ProductA();
15         }
16         else
17             //生成ProductB
18             if(str.equalsIgnoreCase("ProductB"))
19             {
20                 return new ProductB();
21             }
22         return null;
23     }
24 
25 }

客戶端設計

 1 package factory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class Client {
 8     public static void main(String[] args) {
 9         //調用Factory的靜態方法生成所要的類
10         Factory.create("productA");
11         Factory.create("ProductB");
12     }
13 }

控制檯輸出結果:3d

簡單工廠模式實現了生成產品類的代碼跟客戶端代碼分離,在工廠類中你能夠添加所需的生成產品的邏輯代碼,可是問題來了,優秀的java代碼是符合「開放-封閉」原則的,也就是說對擴展開發,對修改關閉,若是你要加一個產品類C,你就要修改工廠類裏面的生成產品的代碼,在這裏你就要增長if-else判斷。對於這個問題,咱們的工廠方法模式就能夠解決這個問題。code

  接下來是工廠方法模式xml

 產品類中增長了ProductC(其餘產品類的代碼是能夠重用上面的,只要把包名更改了就行)。

 1 package factoryMehtod;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 
 8 public class ProductC implements Product {
 9     public ProductC() {
10         System.out.println("productC");
11     }
12 }

聲明工廠接口

 1 package factoryMehtod;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public interface Factory {
 8     //聲明產生產品類的方法
 9     public Product createProduct();
10 }

產生ProductA的FactoryA

 1 package factoryMehtod;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class FactoryA implements Factory {
 8     //實現工廠類的方法生成產品類A
 9     public Product createProduct()
10     {
11         return new ProductA();
12     }
13 
14 }

產生ProductB的FactoryB

 1 package factoryMehtod;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class FactoryB implements Factory {
 8     //實現工廠類的方法生成產品類B
 9     public Product createProduct()
10     {
11         return new ProductB();
12     }
13 }

產生ProductC的FactoryC

 1 package factoryMehtod;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class FactoryC implements Factory {
 8     //實現工廠類的方法生成產品類C
 9     public Product createProduct()
10     {
11         return new ProductC();
12     }
13 }

客戶端

 1 package factoryMehtod;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class Client {
 8     public static void main(String[] args) {
 9         Factory factory;
10         factory = new FactoryA();
11         factory.createProduct();
12         factory = new FactoryB();
13         factory.createProduct();
14         factory = new FactoryC();
15         factory.createProduct();
16     }
17 }

控制檯輸出結果:

   工廠方法模式中咱們把生成產品類的時間延遲,就是經過對應的工廠類來生成對應的產品類,在這裏咱們就能夠實現「開發-封閉」原則,不管加多少產品類,咱們都不用修改原來類中的代碼,而是經過增長工廠類來實現。可是這仍是有缺點的,若是產品類過多,咱們就要生成不少的工廠類。假如咱們要實現的產品接口不止一個,也就是有多個產品接口,不一樣產品接口有對應的產品族。什麼是產品族呢?簡單的理解就是,不一樣牌子產的車裏面會有跑車類型,家庭類型,商用類型等的車,不一樣牌子的車的跑車類型的車能夠組成一個產品族。對於這種狀況咱們能夠採用抽象工廠模式。

   最後是抽象工廠模式,在這裏咱們爲不一樣產品附加上對應的禮物,就是說ProductA中會有GiftA。

增長的Gift接口

1 package abstractFactory;
2 /**
3  * 
4  * @author CIACs
5  *
6  */
7 public interface Gift {
8     //聲明產品贈品的接口,固然也能夠是抽象類,一樣爲了簡單就不聲明方法了
9 }

GiftA類

 1 package abstractFactory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class GiftA implements Gift {
 8     public GiftA()
 9     {
10         System.out.println("GiftA");
11     }
12 }

GiftB類

 1 package abstractFactory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class GiftB implements Gift {
 8     public GiftB()
 9     {
10         System.out.println("GiftB");
11     }
12 }

Factory接口

 1 package abstractFactory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *聲明Product類工廠和Gift類工廠的工同工廠接口
 6  */
 7 public interface Factory {
 8     public Product createProduct();
 9     public Gift createGift();
10 
11 }

生成ProductA和GiftA的FactoryA

 1 package abstractFactory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *FactoryA能夠生成ProductA和GiftA
 6  */
 7 public class FactoryA implements Factory {
 8     @Override
 9     public Product createProduct()
10     {
11         return new ProductA();
12     }
13     @Override
14     public Gift createGift()
15     {
16         return new GiftA();
17     }
18 }

生成ProductB和GiftB的FactoryB

 1 package abstractFactory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *FactoryB能夠生成ProductB和GiftB
 6  */
 7 public class FactoryB implements Factory {
 8     @Override
 9     public Product createProduct() {
10         return new ProductB();
11     }
12     @Override
13     public Gift createGift() {
14         return new GiftB();
15     }
16 
17 }

客戶端

 1 package abstractFactory;
 2 /**
 3  * 
 4  * @author CIACs
 5  *
 6  */
 7 public class Client {
 8     public static void main(String[] args) {
 9         Factory factory;
10         factory = new FactoryA();
11         factory.createProduct();
12         factory.createGift();
13         factory = new FactoryB();
14         factory.createProduct();
15         factory.createGift();
16     }
17 }

控制檯輸出結果:

  抽象工廠模式中咱們能夠定義實現不止一個接口,一個工廠也能夠生成不止一個產品類,抽象工廠模式較好的實現了「開放-封閉」原則,是三個模式中較爲抽象,並具通常性的模式。咱們在使用中要注意使用抽象工廠模式的條件。

 

因爲水平有限,文章中不免有錯誤的地方,歡迎指出錯誤或不足之處,共同進步。歡迎轉載,謝謝
相關文章
相關標籤/搜索