工廠模式是23種設計模式中比較基礎的一種,其目的是隱藏了建立對象的細節,客戶端與具體的實現類解耦,令客戶端可以面向接口編程。數據庫
從簡單到複雜的場景,一共有三種模式。下面拿最多見的球衣做爲例子講解一下,若有不正確的地方請指正,圖片和部分語言摘自網絡,侵刪。編程
假設如今有一個球衣的抽象類,有兩個實現類,一個爲足球球衣,另外一個爲籃球球衣。代碼以下:設計模式
1 abstract class Jersey { 2 abstract public void putOn(); 3 } 4 5 class FootballJersey extends Jersey{ 6 7 @Override 8 public void putOn() { 9 // TODO Auto-generated method stub 10 System.out.println("put on football jersey."); 11 } 12 13 } 14 15 class BasketballJersey extends Jersey { 16 17 @Override 18 public void putOn() { 19 // TODO Auto-generated method stub 20 System.out.println("put on basketball jersey."); 21 } 22 23 }
1. 簡單工廠模式網絡
如今客戶端要使用一個足球球衣的對象,可能你第一個想到的,就是直接new一個對象。Jersey jersey = new FootballJersey();ide
這樣一來,客戶端就和球衣的實現類耦合了,一旦球衣的實現類發生變化,大量的實現類將讓客戶端的代碼維護變得麻煩。函數
還有一種狀況,在實際項目中,可能建立一個對象的時候,須要給它賦值,讀取文件等,這些操做放在構造函數裏會讓對象的建立變得複雜,而若是讓客戶端自行設置,又可能出現代碼重複或設置不正確的狀況。這時,工廠類起到了一個隱藏實現細節的做用。學習
這是Head First 設計模式的理由:ui
簡單工廠模式,就是實現一個工廠類,客戶端根據須要,傳入不一樣的標識,獲得一個實例。spa
1 class SimpleFactory{ 2 3 public static Jersey getJersey(int i) { 4 switch (i) { 5 case 1: 6 return new FootballJersey(); 7 8 case 2: 9 return new BasketballJersey(); 10 11 default: 12 return null; 13 } 14 } 15 }
客戶端調用:設計
1 public static void main(String[] args) { 2 Jersey jersey = SimpleFactory.getJersey(1); 3 if (null != jersey) { 4 jersey.putOn(); 5 } 6 }
示例圖,懶得畫,網上隨便找一個,你們意會
2. 工廠方法模式和抽象工廠模式
上面的代碼
1)客戶端在調用時可能並不知道須要傳入什麼樣的標識。
2)當生產的產品類型增長的時候,必須修改工廠類的代碼,這違背了開閉原則(對擴展開放,對修改關閉)。
3)當生產的產品類型增長的時候,工廠類的代碼會很是臃腫,可能致使上帝類。
爲了解決這個問題,工廠方法模式應運而生。它定義了一個抽象工廠類,產品不是由惟一的一個工廠類實現,而是由具體的子類來實現。
這樣,在產品類型增長的時候,只須要繼承抽象工廠類,實現一個具體的工廠,生產出對應的產品便可。對原來的工廠沒有修改,卻擴展了能力,同時釋放了簡單工廠類的壓力。
對於客戶端來講,須要依賴一個具體的工廠對象。
仍以球衣爲例子,定義一個球衣工廠的抽象類,籃球球衣和足球球衣由各自的工廠類生產。
1 abstract class JerseyFactory { 2 public abstract Jersey createJersey(); 3 } 4 5 class FootballJerseyFactory extends JerseyFactory { 6 7 @Override 8 public Jersey createJersey() { 9 return new FootballJersey(); 10 } 11 } 12 13 class BasketballJerseyFactory extends JerseyFactory { 14 15 @Override 16 public Jersey createJersey() { 17 return new BasketballJersey(); 18 } 19 }
客戶端調用
1 public static void main(String[] args) { 2 JerseyFactory footballJerseyFactory = new FootballJerseyFactory(); 3 Jersey footballJersey = footballJerseyFactory.createJersey(); 4 footballJersey.putOn(); 5 }
此時,須要一件羽毛球球衣,並不須要修改原有的代碼,而是實現一個羽毛球球衣工廠。
示例圖:裏面的ConcreteCreator就是具體的工廠類
3. 抽象工廠模式
抽象工廠模式是工廠方法模式的擴展版,用於生產一系列的產品。
在學習抽象工廠模式之類,先要理解兩個概念:產品族和產品等級結構。
產品等級結構,能夠理解爲產品的繼承結構。好比球衣和它的子類,足球衣,籃球衣,羽毛球衣一塊兒構成了一個等級結構。球鞋和它的子類,足球鞋籃球鞋羽毛球鞋構造等級結構。
產品族,是指同一個工廠中生產的,位於不一樣產品等級結構的一系列產品。
注意,是同一個工廠中生產的一系列產品,意味着一個工廠能夠不僅生產一個產品。
產品位於不一樣的等級結構,如球衣和球鞋,就是不一樣的等級結構。
我我的認爲,產品族能夠理解爲一個解決方案。爲了解決一個實際的問題,從不一樣的等級結構中選取合適的實例,組合成一個產品族。例如,足球衣和足球鞋,就是一個產品族。
經過引進抽象工廠模式,能夠處理具備相同(或者類似)等級結構的多個產品族中的產品對象的建立問題。
當一個工廠等級結構能夠建立出分屬於不一樣產品等級結構的一個產品族中的全部對象時,抽象工廠模式比工廠方法模式更爲簡單、更有效率。
從上面的圖能夠看出,各個產品等級結構之間能夠自由組合,變幻出無窮的產品族。
一般,一個產品族內部的產品,都是有必定的聯繫的,好比足球衣和足球鞋。固然,你要是說就要足球衣配籃球鞋去踢球,那也是闊以的。
上面說了抽象工廠模式是工廠方法模式的擴展版,因此聰明的你從「同一個工廠中生產的一系列產品」能夠得知,所謂擴展,就是工廠類會有多個生產不一樣等級結構的產品的方法。
下面咱們增長球鞋抽象類,並實現足球鞋和籃球鞋。
1 abstract class Shoe { 2 public abstract void putOn(); 3 } 4 5 class FootballShoe extends Shoe { 6 7 @Override 8 public void putOn() { 9 System.out.println("put on football shoes."); 10 } 11 } 12 13 class BasketballShoe extends Shoe { 14 15 @Override 16 public void putOn() { 17 // TODO Auto-generated method stub 18 System.out.println("put on basketball shoes"); 19 } 20 21 }
定義抽象工廠類,能夠生產多個不一樣等級結構的產品。並實現兩個工廠。
1 abstract class EquipmentFactory { 2 public abstract Jersey createJersey(); 3 public abstract Shoe createShoe(); 4 } 5 6 class FootballEquipmentFactory extends EquipmentFactory { 7 8 @Override 9 public Jersey createJersey() { 10 return new FootballJersey(); 11 } 12 13 @Override 14 public Shoe createShoe() { 15 return new FootballShoe(); 16 } 17 } 18 19 class BasketballEquipmentFactory extends EquipmentFactory { 20 21 @Override 22 public Jersey createJersey() { 23 return new BasketballJersey(); 24 } 25 26 @Override 27 public Shoe createShoe() { 28 return new BasketballShoe(); 29 } 30 31 }
某天你想要踢球了,客戶端只須要依賴一個工廠,就能生產出一個產品族。
1 public static void main(String[] args) { 2 EquipmentFactory equipmentFactory = new FootballEquipmentFactory(); 3 Jersey jersey = equipmentFactory.createJersey(); 4 Shoe shoe = equipmentFactory.createShoe(); 5 jersey.putOn(); 6 shoe.putOn(); 7 }
輸出:
在實際的項目中,抽象工廠用得最多的就是用來適應不一樣的數據庫類型。
因爲類型不一樣,得到的數據庫鏈接,數據庫用戶等信息不一樣,可構建一個產品族。
以上~請大神們鞭撻。