簡單工廠(Simple Factory)模式,又稱靜態工廠方法(Static Factory Method)模式,即定義一個工廠類,根據傳入的不一樣參數建立不一樣的產品實例,這些實例對象具備共同的父類或接口。java
簡單工廠模式由一個工廠類、一個產品接口(或抽象類)和一組實現該接口的具體產品組成。這個工廠類根據傳入的參數創造一個具體的產品實現類,並向上轉型爲接口做爲結果返回。數據庫
本節經過一個"喜聞樂見"的豪車系列,展現簡單工廠模式的實現。示例代碼以下:ide
// 產品接口 // public interface ICar { // 抽象類沒法多重繼承,而接口支持多實現,擴展性更好 void drive(); } // 若干具體的產品 // public class Bmw implements ICar { @Override public void drive() { System.out.println("drive a Bmw"); } } public class Benz implements ICar { @Override public void drive() { System.out.println("drive a Benz"); } } public class Audi implements ICar { @Override public void drive() { System.out.println("drive a Audi"); } } // 工廠類 // public class SimpleFactory { private SimpleFactory() {} public static ICar create(String car) { // 工廠不須要有狀態,所以創造產品的方法是靜態的 if ("Bmw".equalsIgnoreCase(car)) { return new Bmw(); // 後續可在工廠裏變動產品類名、構造方法參數甚至實例化方式 } else if ("Benz".equalsIgnoreCase(car)) { return new Benz(); } else if("Audi".equalsIgnoreCase(car)) { return new Audi(); } else { return null; } } }
客戶端經過SimpleFactory.create("BMW").drive()
便可建立Bmw實例並調用其drive()方法。code
如註釋所示,工廠類封裝了產品對象的建立過程,從而可在客戶端不感知的狀況下修改產品的建立方式。例如,若產品類實現了Cloneable接口,就能夠在工廠中用(ICar)Bmw.clone()
替代new Bmw()
。對象
此外,還能夠經過枚舉甚至註解實現簡單工廠模式。以枚舉實現爲例:繼承
public enum EnumCarFactory { BMW { @Override public ICar create() { return new Bmw(); } }, BENZ { @Override public ICar create() { return new Benz(); } }, AUDI { @Override public ICar create() { return new Audi(); } }; public abstract ICar create(); // abstract修飾方法,強制每一個枚舉實現該方法 }
客戶端經過EnumCarFactory.AUDI.create().drive()
或EnumCarFactory.valueOf("AUDI").create().drive()
,便可建立Audi實例並調用其draw()方法。接口
注意,以上實現並不符合開放-封閉原則(對擴展開放,對修改關閉)。例如新增產品時,SimpleFactory工廠內須要添加分支條件,EnumCarFactory工廠內則要添加對應的枚舉定義。這一缺陷能夠經過反射機制來避免:get
public class EnhancedSimpleFactory { private EnhancedSimpleFactory() {} public static <T> T create(Class<? extends T> clazz) { T obj = null; try { obj = (T) Class.forName(clazz.getName()).newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return obj; } }
客戶端經過EnhancedSimpleFactory.create(Benz.class).drive()
,便可建立Benz實例並調用其draw()方法。產品
注意,EnhancedSimpleFactory.create(clazz)
的入參類路徑也可來自配置文件、數據庫等,所以更具靈活性。io
簡單工廠模式的優勢以下:
缺點以下:
隨處可見……