简单工厂+反射+配置文件 进行解耦

解耦具体依赖的方法:

配置文件+反射+简单工厂(完全可以替代工厂模式)

表驱动法解耦

依赖注入解耦(spring使用的就是这种方式)

惯例优于配置

 

下面使用第一种方式进行解耦:

 

通常我们在使用简单工厂模式的时候会由创建方法create通过传入的参数来判断要实例化哪个对象,就像下面这样:

 

    public static class ImageSelectFactory {
        public static IImageSelect createIImageSelect(ImageSelectClientMode mode) {
            IImageSelect imageSelect = null;
            if (mode == ImageSelectClientMode.COLLECTION_IMAGE) {
                imageSelect = new CollectionImage();
            } else if (mode == ImageSelectClientMode.LOCAL_PHOTO) {
                imageSelect = new LocalPhoto();
            } else if (mode == ImageSelectClientMode.WORKS_IMAGE) {
                imageSelect = new WorksImage();
            } else if (mode == ImageSelectClientMode.TAKE_PHOTO) {
                imageSelect = new TakePhoto();
            } else if (mode == ImageSelectClientMode.SUPER_IMAGE_LIB) {
                imageSelect = new SuperImageLib();
            }
            return imageSelect;
        }
    }

这里面定义了5个IImageSelect接口的子类,通过定义好的泛型ImageSelectClientMode来决定实例化哪个子类,现在遇到这么一个问题,如果添加到第6个子类的话,那就必须要更改ImageSelectFactory类以及枚举ImageSelectClientMode,可能你会说“改一下又何妨?”,虽不说影响不影响什么开闭设计原则,但是有个情况你可成想到,你这个类要打包发布给别人用呢?别人在没有源码的情况下如何扩展呢?这里就需要我们动态的通过配置文件来加载实现类了。

 

实现的基本思路为:通过读取本地的.properties文件来获取我们需要实例化的类,然后通过反射来生成对象,这样当你把发布出去的时候,使用者只用更改配置文件就可以让工厂去实例化自己后来才写的实现类,我们看看实现方式:

 

ImageSelectClient.properties:
COLLECTION_IMAGE=com.kongfuzi.student.support.bitmap.select.CollectionImage
LOCAL_PHOTO=com.kongfuzi.student.support.bitmap.select.LocalPhoto
WORKS_IMAGE=com.kongfuzi.student.support.bitmap.select.WorksImage
TAKE_PHOTO=com.kongfuzi.student.support.bitmap.select.TakePhoto
SUPER_IMAGE_LIB=com.kongfuzi.student.support.bitmap.select.SuperImageLib

 

    public static class ImageSelectFactory {
        public static IImageSelect createIImageSelect(String type) {
            IImageSelect mIImageSelect;
 
            //实例化Properties对象,用于读取.properties
            Properties properties = new Properties();
            InputStream is = null;
            try {
                is = ImageSelectClient.class.getResourceAsStream("ImageSelectClient.properties");
                //装载ImageSelectClient.properties文件
                properties.load(is);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
 
            try {
                //根据key获取value,value即为将要实例化的类
                Class<?> aClass = Class.forName(properties.getProperty(type));
                //使用反射进行实例化
                mIImageSelect = (IImageSelect) aClass.newInstance();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return mIImageSelect;
        }
    }


这样,我们就可以随便实现子类,然后在.properties文件中添加对应的包路径,然后通过ImageSelectFactory就可以进行实例化了。

 

 

ref:

https://blog.csdn.net/sahadev_/article/details/49636857

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值