控制反转 IOC 理论推导
阅读原文时间:2022年04月06日阅读:1

控制反转 IOC 理论推导

按照我们传统的开发,我们会先去 dao 层创建一个接口,在接口中定义方法。

public interface UserDao {
    void getUser();
}

然后再去实现类中实现这个方法的作用。

public class UserDaoImpl implements UserDao {
    @Override
    public void getUser() {
        System.out.println("默认获取用户的数据");
    }
}

然后再去 service 层写一个接口,在接口中定义方法。

public interface UserService {
    void getUser();
}

再然后写实现类,实现里面的方法。

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();

    @Override
    public void getUser() {
        userDao.getUser();
    }
}

然后我们使用这业务类

public class MyTest {

    public static void main(String[] args) {
        // 用户实际调用的是业务层,dao 层他们不需要接触
        UserService userService = new UserServiceImpl();
        userService.getUser();
    }

}

最后会输出

默认获取用户的数据

但是现在在 dao 层新增加了一个实现,例如 UserDaomySql

public class UserDaoMysql implements UserDao {
    @Override
    public void getUser() {
        System.out.println("从 MySQL 中获取数据");
    }
}

如果我们想要从 UserDaoMysql 这个类中调用 getUser() 这个方法,就需要在 UserServiceImpl 这个类中修改代码,将创建的 UserDaoImpl 改为 UserMysqlImpl 这个对象。然后才能得到我们想要的效果。

从 MySQL 中获取数据

如果用户就像产品经理一样,今天要你想要在 UserDaoImpl 这个对象中获取数据,明天就想要从 UserDaoMysql 这个对象中获取数据呢?

我们面对这样的问题,是不是还要每次去修改代码,如果我们在很多地方创建了这个对象,岂不是要到处修改,或者有更多的实现类,产品经理又突然叫我们用另一个对象,这样我们就会被折磨死。是吧!

我们都知道猴子的脸说变就变,产品经理何尝不是?

那么我们可以不可以这样做,我们就吧选择权交给产品经理,我们不按照我们的意愿去创建这个对象,我们将这个问题抛给产品经理,诶,我不建,我让他去选,他喜欢用哪个,那就创建哪个。

我们来看看我们在 UserServiceImpl 中创建对象的那条语句

private UserDao userDao = new UserDaoImpl();

我想聪明的你,看到这条语句你就很快能明白,这个不就是定义一个对象变量,然后创建一个对象,将其赋值给它。

那么我们可不可以想个办法,让他动态的将这个对象注入到这个变量里面呢?

聪明的你仔细想想,想想我们创建实体类的时候。

嘿嘿!!!

是不是想到了什么。

我们创建实体类的时候,是不是一开始我们没有为那个变量赋值,是后面才用 Set 赋值的吧。

所以是不是想到该怎么做了,嘿嘿嘿

没错,我们就是写个 Setter

private UserDao userDao;

/**
  * 利用 Set 进行动态实现值的注入
  * @param userDao dao 层的对象
  */
public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
}

我写的和你想的一样吗?我想是的吧。

然后我们使用它

public class MyTest {

    public static void main(String[] args) {
        // 用户实际调用的是业务层,dao 层他们不需要接触
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(new UserDaoMysql());
        userService.getUser();
    }

}

这样我们是不是就可以随便产品经理怎么想了,他爱用啥用啥,让他自己选一个创建就好了。

这样我们是不是就实现了反转,诶,我不创建对象,让你来选,你喜欢哪一个,就用哪一个。