zoukankan      html  css  js  c++  java
  • 用枚举实现工厂方法模式更简洁?

    《编写高质量代码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("无效参数,无法初始化");
            }
            
        }
    }
  • 相关阅读:
    UML中的构件图
    Extjs4 中的gird
    【转载】C#实现线程安全的网络流
    [转载]组播
    【转载】wcf综合运用之:大文件异步断点续传
    【转载】WCF热门问题编程示例(4):WCF客户端如何异步调用WCF服务?
    【转载】特殊用途的IP地址介绍
    [转载]C# HashTable
    c宏定义实战
    c异或加密与解密
  • 原文地址:https://www.cnblogs.com/yanghuahui/p/3308487.html
Copyright © 2011-2022 走看看