控制反转IOC就是把创建对象的任务由“程序”转到“框架”了。
比如:
- UserServiceImpl中依赖UserDao的对象。业务需要使用UserMysqlDaoImpl对象时,就得在程序中new这个对象,需要使用另一个UserOracleDaoImpl对象时,又要new另一个对象。也就需要重复修改程序。
- 这就是传统的将创建对象的任务交给“程序”本身里面了,耦合度高。
- 更好的方式是将创建对象的任务从“程序中”移到“程序外”,也就是在程序员或用户使用UserServiceImpl的对象时,就能决定这个对象内部使用哪个Dao实例对象来完成业务逻辑。
- 实现的方式就是不在UserServiceImpl类中new UserDao对象,而是写一个set函数作为一个接口,使得能从外部传入所需的dao对象。详见改进后的代码。
详见下面的代码示例和注释。
(随意画的图,不规范)
传统的实现:
// uesrDao接口
public interface UserDao{
public void getUser();
}
// UserDao接口的两个实现类
// UserMysqlDaoImpl:基于mysql实现的dao
public class UserMysqlDaoImpl implements UserDao{
@Override
public void getUser() {
System.out.println("连接mysql数据库获取用户数据");
}
}
// UserOracleDaoImpl:基于oracle实现的dao
public class UserOracleDaoImpl implements UserDao{
@Override
public void getUser() {
System.out.println("连接Oracle获取用户数据");
}
}
// UserService接口
public interface UserService{
public void getUser();
}
// UserService接口的实现类
public class UserServiceImpl{
private UserDao userDao = new UserMysqlDaoImpl();// 创建mysqlDao对象
@Override
public void getUser(){
userDao.getUser();
}
}
// 程序员/用户使用UserServiceImpl完成业务逻辑
@Test
public void test(){
UserService service = new UserServiceImpl();
service.getUser();
}
改进后:
// UserService接口的实现类
public class UserServiceImpl{
private UserDao userDao;// 创建mysqlDao对象
// 添加set实现,让选择对象的任务交给程序外部来做,不在程序内部选择创建哪个对象。
public void serUserDao(UserDao userDao){
this.userDao = userDao;
}
@Override
public void getUser(){
userDao.getUser();
}
}
// 程序员/用户使用UserServiceImpl完成业务逻辑
@Test
public void test(){
UserService service = new UserServiceImpl();
// 交给程序员/用户来自主选择new哪个dao传给userService
service.setUserDao(new UserOracleDao());
// 假如又要改为mysql的dao,就可以在程序员/用户阶段重新new一个对象。而不是像之前在程序内部进行创建。
service.seUserDao(new UserMysqlDao());
service.getUser();
}
感谢
参考狂神说讲java做的学习笔记