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


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

 

建議先看下附錄的代碼,然后再看文字說明,附錄代碼展示了:原始工廠方法模式枚舉實現的工廠方法模式

作者(秦小波)認為用枚舉實現工廠方法模式更簡潔,主要原因如下三點:

1.避免錯誤調用的發生,比如

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

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

我認為良好的異常控制就能比較好的解決問題。而且一般動態加載類的時候,也是用Enum.valueof()方法定位枚舉,也會因此拋出異常!

 

2.性能好,使用便捷

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

 

3.降低類間耦合

用原始工廠模式作者認為,調用者需要傳遞一個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("無效參數,無法初始化");
        }
        
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM