用枚舉實現工廠方法模式更簡潔?

《編寫高質量代碼java》建議88--用枚舉實現工廠方法模式更簡潔<質疑>java

 

建議先看下附錄的代碼,而後再看文字說明,附錄代碼展現了:原始工廠方法模式枚舉實現的工廠方法模式程序員

做者(秦小波)認爲用枚舉實現工廠方法模式更簡潔,主要緣由以下三點:ide

1.避免錯誤調用的發生,好比性能

Car car = CarFactory.createCar(Car.class);ui

這樣的代碼在編譯時候不會報錯,運行的時會報InstantiationException,我以爲用枚舉調用實例化的時候,程序員也要指定你調用的是BuickCar仍是FordCar,只是枚舉作了下限定而已。spa

我認爲良好的異常控制就能比較好的解決問題。並且通常動態加載類的時候,也是用Enum.valueof()方法定位枚舉,也會所以拋出異常!code

 

2.性能好,使用便捷blog

枚舉實現,還須要switch,雖然用ordinal()實現了int排序,不過我感受CarFactory.createCar(FordCar.class)連這個開銷都沒有吧?!排序

 

3.下降類間耦合it

用原始工廠模式做者認爲,調用者須要傳遞一個FordCar.class參數才能生產一兩福特汽車,可是用枚舉方法的時候也是要指定枚舉的值才能夠調用,這個並沒有太大區別。

主要我認爲,若是新定義一種汽車,枚舉的EnumCarFactory裏就須要對應新加一個代碼塊,用來實現新加汽車的實例化,原始的工廠模式不須要變,只要新增的汽車類是extends Car!

 

你們也留言說說本身的想法吧。

 

附錄:原始工廠方法模式和枚舉實現的工廠方法模式

interface Car {
    public void myName();
};

class FordCar implements Car {
    public void myName() {
        System.out.println("it's ford");
    }
};

class BuickCar implements Car {
    public void myName() {
        System.out.println("it's buick");
    }
};

/**
 * 原始的工廠模式,新增一個Car子類,徹底無論
 */
class OriginCarFactory {
    public static Car createCar(Class<? extends Car> c) {
        try {
            return (Car) c.newInstance();
        } catch (Exception e) {
            System.out.println("無效參數,沒法初始化");
        }
        return null;
    }
}

/**
 * 枚舉實現工廠模式,一旦新加一個類,還須要在enum中新增對應實例化方法
 */
enum EnumCarFactory {
    FordCar {
        @Override
        public Car create() {
            return new FordCar();
        }        
    },
    BuickCar {
        @Override
        public Car create() {
            return new BuickCar();
        }        
    };

    //abstract修飾方法,強制每一個枚舉實現該方法
    public abstract Car create();
}
public class Main {
    public static void main(String[] args) {
        
        //最經常使用的工廠模式,實例化class
        Car car = OriginCarFactory.createCar(BuickCar.class);
        if(car != null) {
            car.myName();
        }        
        
        //用枚舉模式實例化class
        try {
            car = EnumCarFactory.valueOf("FordCar").create();
            car.myName();
        } catch (Exception e) {
            System.out.println("無效參數,沒法初始化");
        }
        
    }
}
相關文章
相關標籤/搜索