我们新建一个工厂,称为BeanFactory
/**
* 定义一个bean工厂,专门生产普通对象
*/
public class BeanFactory {
public static UserDao getBean() {
return new UserDaoMysqlImpl();
}
}
然后我们要对耦合的那一层修改,目前看是把service解耦了吧?我所有创建对象的操作,都在一个具体的工厂类里;
public class UserServiceImpl implements UserService {
//业务层调用数据dao层,这里不解释了
// private UserDao userDao = new UserDaoMysqlImpl();
// private UserDao userDao = new UserDaoOracleImpl();
private UserDao userDao = BeanFactory.getBean();
public void save() {
userDao.save();
}
}
很明显,我已经进行了service和dao解耦;但是!!!!!!
该死的需求是:我要改成oracle,sqlserver,......
那我们继续:我顺便把之前的getBean换成了mysql的
public class UserServiceImpl implements UserService {
//业务层调用数据dao层,这里不解释了
// private UserDao userDao = new UserDaoMysqlImpl();
// private UserDao userDao = new UserDaoOracleImpl();
// private UserDao userDao = BeanFactory.getMysqlBean();
private UserDao userDao = BeanFactory.getOracleBean();
@Override
public void save() {
userDao.save();
}
}
很明显我现在已经把dao和service的耦合,转移到了工厂和service上了,这就是解耦的一步;但是大家还是疑惑,我感觉我代码增多了?或者更麻烦了?我们继续看
我们每次增加新的业务,扩展,都要修改工厂,所以这个我们可以不可以不在代码里直接做这个事情?--------引出配置文件
我们在resources下定义一个applicationContext.properties
userDao=com.chenxin.gmall.user.demo.dao.UserDaoMysqlImpl
userService=com.chenxin.gmall.user.demo.service.UserServiceImpl
如果我们需要换成oracle,我们只改这个配置文件,改成UserDaoOracleImpl,不需要去动代码
那我们刚刚的BeanFactory就又可以通过读取配置文件的方式,用反射来创建对象,反射创建对象是根据对象的全类名做的,不是直接new,看看效果
/**
* 定义一个bean工厂,专门生产普通对象
*/
public class BeanFactory {
private static Properties properties = new Properties();
//1.加载配置文件
static {
InputStream resourceAsStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
try {
properties.load(resourceAsStream);
resourceAsStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// public static UserDao getMysqlBean() {
// return new UserDaoMysqlImpl();
// }
//
// public static UserDao getOracleBean() {
// return new UserDaoOracleImpl();
// }
public static UserDao getBean(String key){
// 2.使用key获得value
String className = properties.getProperty(key);
// 3.使用value利用反射技术创建对象
try{
return (UserDao) Class.forName(className).newInstance();
}catch(Exception e){
e.printStackTrace();
return null;
}
}
}
好了,我们来需求,我们要保存到oracle,sqlserver数据库,看看你是不是只需要多一个dao的oracle实现,然后去改配置文件就ok?多一个sqlserver后,改下applicationContext.properties
算了我直接写个代码吧:
/**
* 新增了sqlserver的支持,多态的表现
*/
public class UserDaoSqlServerImpl implements UserDao {
@Override
public void save() {
System.out.println("保存SqlServer数据库成功!");
}
}
改下applicationContext.properties
userDao=com.chenxin.gmall.user.demo.dao.UserDaoSqlServerImpl
userService=com.chenxin.gmall.user.demo.service.UserServiceImpl
你可以试一下,是不是这么干的!