反射工厂设计模式

反射工厂设计模式

在这里插入图片描述

顶级父类接口
public interface IBaseDao {
    void add();
}
顶级父类接口的实现类
public class StudentDaoImpl implements IBaseDao {
    public StudentDaoImpl() {
        System.out.println("StudentDaoImpl......");
    }

    @Override
    public void add() {	
        System.out.println("Student...add...");
    }
}
配置文件-供反射使用-根据key取value(全限定名)
StudentDaoImpl = stu.aistar.design.factory.reflect.StudentDaoImpl2
利用枚举特性写一个工具类-用来读取配置文件里面的value(全限定名)
public enum PropUtil {
    INSTANCE;
    // 定义一个Properties属性
    private Properties properties;

    PropUtil(){
        //可以在构造方法 - 初始化的
        //Properties对象就是.properties属性文件[encoding=utf-8]在内存中的映射.
        properties = new Properties();

        //固定的语法 - 死记住
        //获取属性文件字节输入流
        InputStream in = Thread.currentThread()
                         .getContextClassLoader()
                         .getResourceAsStream("stu/aistar/design/factory/reflect/bean.properties");

        try {
            //Properties对象就是.properties属性文件[encoding=utf-8]在内存中的映射.
            properties.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //普通方法
    public String getValue(String key){
        //确认properties不为null
        return properties == null ? null : properties.getProperty(key);
    }
}
创建反射工厂模式-利用刚读取到的全限定名-利用反射技术创建接口的实现类对象-从而对接口的方法进行操作
/**
 * 本类用于演示:反射工厂 - 反射工厂既能够保证在新增一个产品的时候,能够遵守"开闭原则",
 *                      又能够保证始终仅仅只有一个工厂类.
 *  
 *                      Properties + 反射 + 泛型方法/泛型类
 */
public class BaseFactory<T> {

    //面向接口编程
    //泛型方法 - 静态方法<T>,同时也要设置泛型类
    public T getInstance(String type){
        T t = null;
        //传进来的type是一个全限定类型,我们需要用forName方法
        try {
            //获取class实例的方式
            Class<?> c = Class.forName(type);
            //反射调用空参构造
            try {
                t = (T) c.newInstance();  //构造空参  可以调用接口实现类中的方法

            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return t;
    }
}
单元测试
public class FactoryTest {
    public static void main(String[] args) {
        //1. 获取StudentDaoImpl对象
        //有多少个产品实现类 - 都是需要配置到bean.properties文件中的.
        String stuClass = PropUtil.INSTANCE.getValue("StudentDaoImpl"); //获取的是全限定类型

        BaseFactory<StudentDaoImpl> baseFactory = new BaseFactory<>();

//        IBaseDao stuDao = baseFactory.getInstance(stuClass);
//
//        stuDao.add();

        //思考好处
        /**
         * 场景:如果哪天实现类功能升级了.
         * 当一个类的功能拓展之后,尽量不要去动原来的类 - “开闭原则”
         * 解决方案一:不推荐,再去写一个类StudentDaoImpl2.java extends StudentDaoImpl.java
         * 继承虽然解决了功能的拓展,同时也增加了类之间的耦合性 - “高内聚,低耦合”
         *
         * 解决方案二:引导如果想要对一个类进行功能的拓展,使用设计原则 - 合成复用原则来替代继承的写法.
         *
         * 设计原则 - 依赖倒置原则 - 由维护具体-维护抽象.
         *
         * 凡是代码中用到StudentDaoImpl,代码需要大量的改动
         * 代码改动 - 小牧编译 - 重新部署
         * IBaseDao stuDao = new StudentDaoImpl();
         *
         * 只需要修改配置文件即可
         * STUDENT_DAO=tech.aistar.design.factory.reflect.StudentDaoImpl2
         */
        IBaseDao stuDao = baseFactory.getInstance(stuClass);
        stuDao.add();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值