java反射思想以及工厂设计模型(一)

反射

  • 实例化Class类对象
    所谓的框架开发 :本质就是==Java可重用性设计思想+反射机制+XML配置(Annotation配置)

1.Class类:
Class是一切反射的源头,但是如果要想取得Class类的对象,在java中存在有三种做法:
1.利用Object类中的getClass()方法:
方法:public final Class<?> getClass();
取得Class类中包裹的类型名称:public String getName();
这里写图片描述

这种方式平时可能很少用,但是再进行架构设计时开发时,(框架开发)必须使用到反射。

2.利用“类.class”完成

这里写图片描述

与以上结果一样

此时的类并没有实例化对象产生,只是简单的引用了一个类的名称而已。–这种操作可以减少实例化对象的产生,节省空间
学习Hibernate框架的时候会用到。

3.使用Class类中提供的static方法处理:
取得Class对象:
public static Class<?> forName(String className) throws ClassNotFoundException

这里写图片描述

利用forName()方法实现的Class类对象实例化的最大好处在于:可以利用字符串来进行设置。此时保证类暂时不存在。(后边再动态配置)
在JDBC里边使用的就是此类方式进行数据库驱动的加载。

Class是整个反射的源头。

  • 反射实例化对象

取得了Class类对象严格来讲并不是为了取得类名称而准备的,其核心的意义在于,可以通过反射达到关键字new的使用目的,而这一操作如果要使用那么就必须结合Class类中的如下方法:

1)反射实例化对象
public T newInstance() throws InstantiationException,IllegalAccessException

范例:反射实例化对象操作:

这里写图片描述

而我们最关键的是”cls.newInstance()”是调用给定类型的
(“cn.mldn.demo.Emp”)中的无参构造方法。
此处一定要跟上包名称。

只能调用无参构造方法,如果这个类此时没有无参构造方法,那么代码将出现异常。
这就是为什么开发要求的基础类 简单java类中提供无参构造方法。

总结:
利用反射最大的特点在于:
实例化Class类对象的时候,指定的类可以暂时不存在;
利用我们的发射可以避免new关键字所带来的耦合问题,使代码更加灵活。

  • 反射与工厂设计模式
    对于工厂设计模式应该已经不陌生了,工厂设计模式最大的好处是避免了接口与子类的耦合问题。但是既然已经谈到了工厂设计,下面就编写一个工厂设计模式。

简单工厂设计模式。

package com.wanghaoxin.demo;

interface IUserDao{
    public boolean doCreate();
}
class OracleUserDaoImpl implements IUserDao{

    @Override
    public boolean doCreate() {
        System.out.println("Oracle执行------------");
        return true;
    }
}
class Factory{
    public static IUserDao getIUserDaoInstance(){
        return new OracleUserDaoImpl();
    }
}
public class TestFactory {
    public static void main(String[] args) {
        IUserDao dao = Factory.getIUserDaoInstance();
        dao.doCreate();
    }
}

这个工厂是一种最简单的静态工厂设计,其目的是避免了客户端接口与具体子类的耦合问题,如果继续依照以上概念来进行分析,那么有可能会出有可能会出现专门适合于MySql的数据库的实现子类。

//新增
class MySQLUserDaoImpl implements IUserDao{

    @Override
    public boolean doCreate() {
        System.out.println("MySQL执行------------");
        return true;
    }
}
//修改工厂类
class Factory{
    public static IUserDao getIUserDaoInstance(){
        //return new OracleUserDaoImpl();
        return new MySqlUserDaoImpl();
    }
}

世界上的数据库种类太多了,那么此时的代码会出现一个非常明显的问题了,如果每次更换子类都要去修改工厂。
为了方便的控制项目可能使用到的数据库,最好的做法是利用配置文件来进行处理。

优化流程图:
这里写图片描述

1.新建一个一个database.properties
db.name=MySQL
2.新建一个MySQL.properties的文件
user.class=com.wanghaoxin.demo.MySQLUserDaoImpl
3.新建一个Oracle.properties
user.class=com.wanghaoxin.demo.OracleUserDaoImpl

两个数据库操作子类的文件的key名称必须一样
改善工厂设计模式

package com.wanghaoxin.demo;

import java.util.ResourceBundle;

interface IUserDao{
    public boolean doCreate();
}
class ResourceUtil{
    public static String getValue(String baseName,String key){
        return ResourceBundle.getBundle(baseName).getString(key);
    }
}
class MySQLUserDaoImpl implements IUserDao{

    @Override
    public boolean doCreate() {
        System.out.println("MySql执行------------");
        return true;
    }
}
class OracleUserDaoImpl implements IUserDao{

    @Override
    public boolean doCreate() {
        System.out.println("Oracle执行------------");
        return true;
    }
}
class Factory{
    public static IUserDao getIUserDaoInstance() throws Exception{
        //return new OracleUserDaoImpl();
        //return new MySqlUserDaoImpl();
        String dbName = ResourceUtil.getValue("database", "db.name");
        String userClassName = ResourceUtil.getValue(dbName, "user.class");
        return (IUserDao) Class.forName(userClassName).newInstance();

    }
}
public class TestFactory {
    public static void main(String[] args) throws Exception {
        IUserDao dao = Factory.getIUserDaoInstance();
        dao.doCreate();
    }
}

结果可以正常执行。
这一切设计都源自于反射机制,在以后的开发里面可能会出现配置信息更多的情况,那么这样只能依赖XML结构来处理了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值