我们的main函数中,使用了new StudentDaoImpl() 即创建实现类的实例来构造StudentDao对象的方式。
如果我们要进一步的优化代码,也即是说,要降低耦合性(具体的类(名)和main函数相分离)
我们使用工厂模式(建立一个工厂类来生产StudentDaoImpl的实例(这个产品))
在工厂类中我们可以用类名通过Class.forName()来创建类的实例
所以我们进一步分离,将类的名字和工厂类相分离,放在配置文件中(通过键值对的方式)
所以现在我们的过程是:
配置文件中的类名通过键值对取出------>工厂类中通过Class.forName()构造出类的实例---->主函数中通过使用工厂模式的单例来调用返回学生类对象的方法来获得
public class DaoFactory {
private static StudentDao studentDao = null; //工厂产品
private static DaoFactory instance = null; //单例
private DaoFactory(){ //构造方法私有化
try {
Properties prop = new Properties();
InputStream inStream = new FileInputStream(new File("src/daoconfig.properties"));
prop.load(inStream);
String studentDaoClass = prop.getProperty("studentDaoClass");
//以上是从配置文件读取,降低耦合性
studentDao = (StudentDao)Class.forName(studentDaoClass).newInstance();
//根据实现类的名字来构造实现类的实例(并转化为接口类型)
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static DaoFactory getInstance(){ //返回单例
if(instance == null){ //第一次以后不为空就不会再进去加锁了
synchronized(DaoFactory.class){
if(instance == null){ //处理多线程并发问题
instance = new DaoFactory(); //懒加载,提高效率
}
}
}
return instance;
}
public StudentDao getStudentDao(){ //获取学生类对象的实例方法
return studentDao;
}
单例模式就是要只有一个对象实例,所以要私有化构造方法
并且在类中构造一个私有实例对象,并提供静态公有方法来返回获取这个对象
并且在方法中getInstance有懒加载,所以需要处理并发问题,又为了提高效率,采用了双重检查的方式。即构造了对象实例以后,就不会再进去加锁和检查了。
至于另一个方法getStudentDao是工厂类生产产品的实例方法(准确说是出售产品,生产是在构造方法中),通过获取到的单例来调用:
StudentDao studentDao = DaoFactory.getInstance().getStudentDao();
以上改变了在主函数中
StudentDao studentDao = new StudentDaoImpl();
的获取对象的方式。降低了程序结构之间的耦合性。