Java設計模式之三種工廠模式

工廠模式實現了建立者和調用者的分離,實現了更好的解耦。java

 

詳細分類:程序員

1) 簡單工廠模式(靜態工廠模式);
2) 工廠方法模式;編程

3) 抽象工廠模式ide

 

面向對象設計的基本原則:工具

1)       OCP(開閉原則, Open-Closed Principle):一個軟件的實體應當對擴展開放,對修改關閉。ui

2)       DIP(依賴倒轉原則,Dependence Inversion Principle):要針對接口編程,不要針對實現編程。編碼

3)       LoD(迪米特法則, Law of Demeter):只與你直接的朋友通訊,而避免和陌生人通訊。spa

 

1、簡單工廠模式(靜態工廠模式)

我喜歡吃麪條,抽象一個麪條基類,(接口也能夠),這是產品的抽象類。設計

1 public abstract class INoodles { 2 /** 3  * 描述每種麪條啥樣的 4 */ 5 public abstract void desc(); 6 }

先來一份蘭州拉麪(具體的產品類):3d

1 public class LzNoodles extends INoodles { 2  @Override 3 public void desc() { 4 System.out.println("蘭州拉麪 上海的好貴 家裏才5 6塊錢一碗"); 5  } 6 }

程序員加班必備也要吃泡麪(具體的產品類):

1 public class PaoNoodles extends INoodles { 2  @Override 3 public void desc() { 4 System.out.println("泡麪好吃 可不要貪杯"); 5  } 6 }

還有我最愛吃的家鄉的幹扣面(具體的產品類):

1 public class GankouNoodles extends INoodles { 2  @Override 3 public void desc() { 4 System.out.println("仍是家裏的幹扣面好吃 6塊一碗"); 5  } 6 }

準備工做作完了,咱們來到一家「簡單面館」(簡單工廠類),菜單以下:

 1 public class SimpleNoodlesFactory {  2 public static final int TYPE_LZ = 1;//蘭州拉麪  3 public static final int TYPE_PM = 2;//泡麪  4 public static final int TYPE_GK = 3;//幹扣面  5  6 public static INoodles createNoodles(int type) {  7 switch (type) {  8 case TYPE_LZ:  9 return new LzNoodles(); 10 case TYPE_PM: 11 return new PaoNoodles(); 12 case TYPE_GK: 13 default: 14 return new GankouNoodles(); 15  } 16  } 17 }

簡單面館就提供三種麪條(產品),你說你要啥,他就給你啥。這裏我點了一份幹扣面:

1 /** 2  * 簡單工廠模式 3 */ 4 INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_GK); 5 noodles.desc()

 

要點:
1)簡單工廠模式也叫靜態工廠模式,就是工廠類通常使用靜態方法,經過接收的參數的不一樣的對象的不一樣來返回不一樣的對象實例。
2)對於增長新產品無能爲力!不修改代碼的話,是沒法擴展的。
3)通常使用較多仍是簡單工廠模式。

2、工廠方法模式

工廠方法模式要點:

1)爲了不簡單工廠模式的缺點,不徹底知足OCP(開閉原則)

2)工廠方法模式和簡單工廠模式最大的不一樣在於,簡單工廠模式只有一個(對於一個項目或者一個獨立模塊而言)工廠類,而工廠方法模式有一組實現了相同接口的工廠類。

Car.java接口的源碼:

工廠方法模式更加符合開閉原則弊端是每次擴展都會增長新的類。

3、簡單工廠模式和工廠方法模式PK

1)結構複雜度

  從這個角度比較,顯然簡單工廠模式要佔優,簡單工廠模式只須要一個工廠類,而工廠方法模式的工廠類隨着產品類的個數增長而增長,這無疑會使類的個數愈來愈多,從而增長告終構的複雜程度。

 

2)代碼複雜度

   代碼複雜度和結構複雜度是一對矛盾,既然簡單工廠模式在結構方面相對簡潔,那麼它在代碼方面確定是比工廠方法模式複雜的了。簡單工廠模式的工廠類隨着產品類的增長鬚要增長更多方法(或代碼)。

 

3)客戶端編程難度

   工廠方法模式雖然在工廠類結構中引入了接口從而知足了OCP,可是在客戶端編碼中須要對工廠類進行實例化。而簡單工廠模式的工廠類是個靜態類,在客戶端無需實例化,這無疑是個吸引人的優勢。

 

4)管理上的難度

   這是個關鍵的問題。

   咱們先談擴展。衆所周知,工廠方法模式徹底知足OCP,即它有很是良好的擴展性。那是否就說明了簡單工廠模式就沒有擴展性呢?答案是否認的,簡單工廠模式一樣具有良好的擴展性-----擴展的時候僅須要修改少許的代碼(修改工廠類的代碼)就能夠知足擴展性的要求了。儘管這沒有徹底知足OCP,但咱們不須要太拘泥於設計理論,要知道,sun提供的java官方工具包中也有不少沒有知足OCP的例子啊。

   而後咱們從維護性的角度分析下,假如某個具體產品類須要進行必定的修改,極可能須要修改對應的工廠類。當同時須要修改多個產品類的時候,對工廠類的修改會變得至關麻煩(對號入座已是個問題了)。反而簡單工廠沒有這些問題,當多個產品類須要修改時,簡單工廠模式仍然僅僅須要修改惟一的工廠類(不管怎樣都能改到知足要求吧?大不了把這個類重寫)。

 

根據設計理論建議:工廠方法模式。但實際上,咱們通常都用了簡單工廠模式

4、抽象工廠模式

定義:爲建立一組相關或相互依賴的對象提供一個接口,並且無需指定他們的具體類。

類型:建立類模式

類圖:

 

抽象工廠模式與工廠方法模式的區別

        抽象工廠模式是工廠方法模式的升級版本,他用來建立一組相關或者相互依賴的對象。他與工廠方法模式的區別就在於,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式則是針對的多個產品等級結構。在編程中,一般一個產品結構,表現爲一個接口或者抽象類,也就是說,工廠方法模式提供的全部產品都是衍生自同一個接口或抽象類,而抽象工廠模式所提供的產品則是衍生自不一樣的接口或抽象類。

        在抽象工廠模式中,有一個產品族的概念:所謂的產品族,是指位於不一樣產品等級結構中功能相關聯的產品組成的家族。抽象工廠模式所提供的一系列產品就組成一個產品族;而工廠方法提供的一系列產品稱爲一個等級結構。咱們依然拿生產汽車的例子來講明他們之間的區別。

        在上面的類圖中,兩廂車和三廂車稱爲兩個不一樣的等級結構;而2.0排量車和2.4排量車則稱爲兩個不一樣的產品族。再具體一點,2.0排量兩廂車和2.4排量兩廂車屬於同一個等級結構,2.0排量三廂車和2.4排量三廂車屬於另外一個等級結構;而2.0排量兩廂車和2.0排量三廂車屬於同一個產品族,2.4排量兩廂車和2.4排量三廂車屬於另外一個產品族。

        明白了等級結構和產品族的概念,就理解工廠方法模式和抽象工廠模式的區別了,若是工廠的產品所有屬於同一個等級結構,則屬於工廠方法模式;若是工廠的產品來自多個等級結構,則屬於抽象工廠模式。在本例中,若是一個工廠模式提供2.0排量兩廂車和2.4排量兩廂車,那麼他屬於工廠方法模式;若是一個工廠模式是提供2.4排量兩廂車和2.4排量三廂車兩個產品,那麼這個工廠模式就是抽象工廠模式,由於他提供的產品是分屬兩個不一樣的等級結構。固然,若是一個工廠提供所有四種車型的產品,由於產品分屬兩個等級結構,他固然也屬於抽象工廠模式了。

 1 interface IProduct1 {  2 public void show();  3 }  4 interface IProduct2 {  5 public void show();  6 }  7  8 class Product1 implements IProduct1 {  9 public void show() { 10 System.out.println("這是1型產品"); 11  } 12 } 13 class Product2 implements IProduct2 { 14 public void show() { 15 System.out.println("這是2型產品"); 16  } 17 } 18 19 interface IFactory { 20 public IProduct1 createProduct1(); 21 public IProduct2 createProduct2(); 22 } 23 class Factory implements IFactory{ 24 public IProduct1 createProduct1() { 25 return new Product1(); 26  } 27 public IProduct2 createProduct2() { 28 return new Product2(); 29  } 30 } 31 32 public class Client { 33 public static void main(String[] args){ 34 IFactory factory = new Factory(); 35  factory.createProduct1().show(); 36  factory.createProduct2().show(); 37  } 38 }

抽象工廠模式的優勢:

        抽象工廠模式除了具備工廠方法模式的優勢外,最主要的優勢就是能夠在類的內部對產品族進行約束。所謂的產品族,通常或多或少的都存在必定的關聯,抽象工廠模式就能夠在類內部對產品族的關聯關係進行定義和描述,而沒必要專門引入一個新的類來進行管理。

抽象工廠模式的缺點:

       產品族的擴展將是一件十分費力的事情,假如產品族中須要增長一個新的產品,則幾乎全部的工廠類都須要進行修改。因此使用抽象工廠模式時,對產品等級結構的劃分是很是重要的。

適用場景:

       當須要建立的對象是一系列相互關聯或相互依賴的產品族時,即可以使用抽象工廠模式。說的更明白一點,就是一個繼承體系中,若是存在着多個等級結構(即存在着多個抽象類),而且分屬各個等級結構中的實現類之間存在着必定的關聯或者約束,就可使用抽象工廠模式。假如各個等級結構中的實現類之間不存在關聯或約束,則使用多個獨立的工廠來對產品進行建立,則更合適一點。

 

工廠模式要點:

1)簡單工廠模式(靜態工廠模式)     雖然某種程度不符合設計原則,但實際使用最多。

2)工廠方法模式    不修改已有類的前提下,經過增長新的工廠類實現擴展。

3)抽象工廠模式    不能夠增長產品,能夠增長產品族

應用場景:

1)JDK中CalendargetInstance方法

2)JDBC中Connection對象的獲取;

3)Hibernate中SessionFactory建立Session;

4)Spring中IOC容器建立管理bean對象

5)XML解析時的DocumentBuilderFactory建立解析器對象;

6)反射中Class對象的newInstance()。

相關文章
相關標籤/搜索