什么是IOC
控制反转 IoC ( Inversion of Control ),一种设计思想,指的是获得依赖对象的方式反转了。
从前,程序是主动创建对象,控制权在程序员手中,有了ioc容器后,控制权在客户手中,由ioc容器去创建,
因此程序由原来的主动创建变成被动接收,所以被形容为控制反转(Inversion of Control IoC)
IOC的优点
成本代价的降低
解耦
1、把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,方便测试,利于功能复用。
2、从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IOC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源。
测试
对比之前的流程
1、UserDao接口
public interface UserDao {
public void getUser();
}
2、UserDaoImpl实现类
public class UserDaoImpl implements UserDao {
@Override
public void getUser() {
System.out.println("获取用户数据");
}
}
3、UserService业务接口
public interface UserService {
public void getUser();
}
4、UserServiceImpl业务实现类
private UserDao userDao = new UserDaoImpl();
@Override
public void getUser() {
userDao.getUser();
}
5、测试
public class MyTest{
@Test
public void test(){
UserService service = new UserServiceImpl();
service.getUser();
}
}
增加多个需求
1、增加UserDaoMySqlImpl类
public class UserDaoMySqlImpl implements UserDao{
@Override
public void getUser() {
System.out.println("MySql获取用户数据");
}
}
紧接着去使用MySql的话 , 我们就需要去service实现类里面修改对应的实现
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoMySqlImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
2、若再增加一个Userdao的实现类 ,
public class UserDaoOracleImpl implements UserDao{
@Override
public void getUser() {
System.out.println("Oracle获取用户数据");
}
}
又需要去service实现类里面修改对应的实现 ,假设我们的这种需求非常大 ,这种方式就根本不适用了,每次变动,都需要修改大量代码,这种设计的耦合性太高了, 牵一发而动全身.
使用Set实现
public class UserServiceImpl implements UserService{
private UserDao userDao;
//利用set实现
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
再去测试:
@Test
public void test(){
UserServiceImpl service = new UserServiceImpl();
service.setUserDao( new UserDaoMySqlImpl() );
service.getUser();
//那我们现在又想用Oracle去实现呢
service.setUserDao( new UserDaoOracleImpl() );
service.getUser();
}
这种思想,从本质上解决了问题,程序猿不需要再去管理对象的创建了.系统的耦合性大大降低,可以更加专注于业务的实现上,这就是IOC的原型.