在設計原則中有這樣一句話“我們應該針對接口編程,而不是正對實現編程”。但是我們還是在一直使用new關鍵字來創建一個對象,這不就是在針對實現編程么?
針對接口編程,可以隔離掉以后系統可能發生的一大堆改變。入股代碼是針對接口而寫,那么可以通過多態,它可以與任何新類實現該接口。但是,當代碼使用一大堆的具體類時,等於是自找麻煩,因為一旦加入新的具體類,就必須要改變代碼。在這里我們希望能夠調用一個簡單的方法,我傳遞一個參數過去,就可以返回給我一個相應的具體對象,這個時候我們就可以使用簡單工廠模式。
一、基本定義
簡單工廠模式又稱之為靜態工廠方法,屬於創建型模式。在簡單工廠模式中,可以根據傳遞的參數不同,返回不同類的實例。簡單工廠模式定義了一個類,這個類專門用於創建其他類的實例,這些被創建的類都有一個共同的父類。
二、模式結構
模式結構圖如下:
模式分析:
Factory:工廠角色。專門用於創建實例類的工廠,提供一個方法,該方法根據傳遞的參數不同返回不同類的具體實例。
Product:抽象產品角色。為所有產品的父類。
ConcreteProduct:具體的產品角色。
簡單工廠模式將對象的創建和對象本身業務處理分離了,可以降低系統的耦合度,使得兩者修改起來都相對容易些。當以后實現改變時,只需要修改工廠類即可。
三、簡單工廠模式實現
模式場景:在一個披薩店中,要根據不同客戶的口味,生產不同的披薩,如素食披薩、希臘披薩等披薩。
該例的UML結構圖如下:
代碼實現
Pizza制造工廠:SimplyPizzaFactory.java
1 /** 2 * 專門用於創建披薩的工廠類 3 */ 4 public class SimplePizzaFactory { 5 public Pizza createPizza(String type){ 6 Pizza pizza = null; 7 8 if(type.equals("cheese")){ 9 pizza = new CheesePizza(); 10 } 11 else if(type.equals("clam")){ 12 pizza = new ClamPizza(); 13 } 14 else if(type.equals("pepperoni")){ 15 pizza = new PepperoniPizza(); 16 } 17 else if(type.equals("veggie")){ 18 pizza = new VeggiePizze(); 19 } 20 21 return pizza; 22 } 23 }
抽象披薩:Pizza.java
1 /** 2 * 抽象pizza類 3 */ 4 public abstract class Pizza { 5 public abstract void prepare(); 6 7 public abstract void bake(); 8 9 public abstract void cut(); 10 11 public abstract void box(); 12 }
具體披薩:CheesePizza.java
1 public class CheesePizza extends Pizza{ 2 3 @Override 4 public void bake() { 5 System.out.println("bake CheesePizza ..."); 6 } 7 8 @Override 9 public void box() { 10 System.out.println("box CheesePizza ..."); 11 } 12 13 @Override 14 public void cut() { 15 System.out.println("cut CheesePizza ..."); 16 } 17 18 @Override 19 public void prepare() { 20 System.out.println("prepare CheesePizza ..."); 21 } 22 23 }
PizzaStore.java
1 public class PizzaStore { 2 SimplePizzaFactory factory; //SimplePizzaFactory的引用 3 public PizzaStore(SimplePizzaFactory factory){ 4 this.factory = factory; 5 } 6 7 public Pizza orderPizza(String type){ 8 Pizza pizza; 9 pizza = factory.createPizza(type); //使用工廠對象的創建方法,而不是直接new。這里不再使用具體實例化 10 11 pizza.prepare(); 12 pizza.bake(); 13 pizza.cut(); 14 pizza.box(); 15 16 return pizza; 17 } 18 }
四、簡單工廠模式的優缺點
優點
1、簡單工廠模式實現了對責任的分割,提供了專門的工廠類用於創建對象。
2、客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對於一些復雜的類名,通過簡單工廠模式可以減少使用者的記憶量。
3、通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。
缺點
1、由於工廠類集中了所有產品創建邏輯,一旦不能正常工作,整個系統都要受到影響。
2、使用簡單工廠模式將會增加系統中類的個數,在一定程序上增加了系統的復雜度和理解難度。
3、系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能造成工廠邏輯過於復雜,不利於系統的擴展和維護。
4、簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構。
五、簡單工廠模式的使用場景
1、 工廠類負責創建的對象比較少。
2、 客戶端只知道傳入工廠類的參數,對於如何創建對象不關心。
六、總結
1、 簡單工廠模式的要點就在於當你需要什么,只需要傳入一個正確的參數,就可以獲取你所需要的對象,而無須知道其創建細節。
2、 簡單工廠模式最大的優點在於實現對象的創建和對象的使用分離,但是如果產品過多時,會導致工廠代碼非常復雜。