需求
** 实际开发中由于客户的数据库环境经常变化,客户希望更换数据库时候,只需要修改dao(数据访问层)的代码,不需要修改service(业务层)的代码,这个时候就需要根据开闭原则使用到耦合性很低的技术了,保证不动源码的情况下进行程序的拓展开发是开发者必备技能之一。下面我们通过一段代码来实现对IOC容器工厂模式解耦的应用.**
1)先设计Dao接口和实现
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:26
*/
public interface UserDao {
public void save();
}
在设计一个mysql实现,因为是测试所以并不是真的连接数据库.
package com.mobaijun.dao.impl;
import com.mobaijun.dao.UserDao;
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:27
*/
public class UserDaoMysqlImpl implements UserDao {
@Override
public void save() {
System.out.println("数据库已经保存到MySQL数据库了");
}
}
2)设计一个Service接口和实现
package com.mobaijun.service;
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:28
*/
public interface UserService {
public void save();
}
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:30
* 业务层
*/
public class UserServiceImpl implements UserService {
//创建具体Dao实现对象
private UserDao userDao = new UserDaoMySQLImpl();
@Override
public void save() {
userDao.save();
}
}
3)在maven工程test创建测试类UserServiceTest测试类
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:31
* 测试类
*/
public class UserServiceTest {
@Test
public void testSave(){
UserService userService = new UserServiceImpl();
userService.save();
}
}
这时,需要从MySQL切换到Oracle数据库,根据开闭原则,扩展了Dao实现
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:32
*/
public class UserDaoOracleLImpl implements UserDao {
@Override
public void save() {
System.out.println("数据已经保存到oracle数据库啦");
}
}
这时业务层修改源代码,切换Dao
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:33
*/
public class UserServiceImpl implements UserService {
//创建具体Dao实现对象
//private UserDao userDao = new UserDaoMySQLImpl();
//切换Dao实现类
private UserDao userDao = new UserDaoOracleLImpl();
这样不太好,每次都需要修改Service的源代码,Service和Dao的耦合性太高!
那么怎么办?这时我们就可以使用工厂模式(Factory)解决问题!
设计一个对象工厂,创建UserDao实现类
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:36
* 创建对象(UserDao实现类对象)
*/
public class BeanFactory {
public static UserDao getBean(){
return new UserDaoMySQLImpl();
}
}
这时,业务每次需要Dao从工厂获取,好处是没有修改Dao,不用修改Service
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:39
* 业务层
*/
public class UserServiceImpl implements UserService {
//创建具体Dao实现对象
//private UserDao userDao = new UserDaoMySQLImpl();
//切换Dao实现类
//private UserDao userDao = new UserDaoOracleLImpl();
//从工厂获取对象
private UserDao userDao = BeanFactory.getBean();
但是还有问题,BeanFactory每次都修改代码,耦合也是太高,思路:可不可以 不用使用配置文件配置创建对象,BeanFactory改造成更加通用的工厂?是可以的 !我们通过使用配置文件
在resources包下创建bean.properties配置文件配置存放链接数据库的配置文件
userDao=com.mobaijun.dao.impl.UserDaoMySQLImpl
userService=com.mobaijun.service.impl.UserServiceImpl
这时修改BeanFacotry
/**
* @Author:Auser·杰
* @DATE:2019/8/18 15:50
* 创建工厂对象
*/
public class BeanFactory {
//ResourceBundle读取properties{配置文件}
private static ResourceBundle bundle;
/*public static UserDao getBean(){
return new UserDaoOracleLImpl();
}*/
/**
* 读取bean.properties创建对应的对象
* @return
*/
public static Object getBean(String key){
//1.读取bean.properties
if(bundle==null){
bundle = ResourceBundle.getBundle("bean");
}
//2.通过key获取value
String className = bundle.getString(key);
//3.通过反射创建对象
try {
return Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
最后,Service和测试代码
/**
* @Author:Auser·杰
* @DATE:2019/8/18 16:12
*/
public class UserServiceImpl implements UserService {
//创建具体Dao实现对象
//private UserDao userDao = new UserDaoMySQLImpl();
//切换Dao实现类
//private UserDao userDao = new UserDaoOracleLImpl();
//从工厂获取对象
private UserDao userDao = (UserDao)BeanFactory.getBean("userDao");
/**
* @Author:Auser·杰
* @DATE:2019/8/18 16:20
*测试类
*/
public class UserServiceTest {
@Test
public void testSave(){
UserService userService = (UserService) BeanFactory.getBean("userService");
userService.save();
}
}
总结 ,在使用工厂模式的时候,我们明显的让Service和Dao的耦合降低了!