Java設計模式:Simple Factory(簡單工廠)模式

概念定義

簡單工廠(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

模式優缺點

簡單工廠模式的優勢以下:

  • 解耦:將對象的建立和使用過程分開(客戶端只接觸產品接口),下降對象和客戶端的耦合關係。
  • 下降代碼重複: 將建立對象的過程集中於工廠內部,當建立對象較爲複雜且頻繁建立時,能夠減小重複性代碼。
  • 下降維護成本:建立過程由工廠統一管理,當業務邏輯變動時在工廠裏修改便可,而無需逐個修正全部須要建立對象的地方。

缺點以下:

  • 簡單工廠使用靜態工廠方法,靜態方法不能被繼承和重寫,所以工廠角色沒法造成基於繼承的等級結構。
  • 簡單工廠容易違背開放-封閉原則(雖然能夠經過反射機制改善),可能致使工廠邏輯過於複雜。
  • 工廠類集中負責全部產品對象的建立邏輯,一旦工廠不能正常工做,整個系統都會受到影響。

業界實踐

隨處可見……

相關文章
相關標籤/搜索