控制反转(IOC)就是Spring中两个主要的概念之一,另外一个就是AOP(面向切面),它的主要思路应用动态代理,这里不详细展开。下面通过一个简单的例子来介绍一下IOC。假设一个场景:目前有三个角色,买水果的人(用户),卖水果的人(业务层),水果(持久化层),
先写一个接口,
public interface Fruit {
public void get();
}
现在实现3种水果的类,为了方便展示,把它们先写在一起,// Apple.java
public class Apple implements Fruit{
public void get() {
System.out.println("get an apple");
}
}
// Orange.java
public class Banana implements Fruit{
public void get() {
System.out.println("get a banana");
}
}
// Banana.java
public class Orange implements Fruit{
public void get() {
System.out.println("get a organe");
}
}
现在实现一个业务层,也就是从3个水果类中获取水果,// UserService.java
public class UserService {
private Fruit fruit = new Apple();
public void getFruit() {
fruit.get();
}
}
然后,实现一个用户类,// User.java
public class User {
public static void main(String[] args) {
UserService user = new UserService();
user.getFruit();
}
}
上述就是我们实现一个程序的惯用方式,这样看上去没有什么问题,目前我们调用业务层UserService获取到苹果,那么试想一下,如果现在我想获取橘子怎么办?这样就需要修改业务层代码,
// UserService.java
public class UserService {
private Fruit fruit = new Orange();
public void getFruit() {
fruit.get();
}
}
也许很多同学会认为这样没什么问题,那就修改一下业务层代码啊?
显然,这不是一个优秀的程序员做的事情,每当用户需求做出改变时,我们的代码都要做出相应的修改,那么有两个问题,
- 如果工程量较大,修改的内容较多怎么办?
- 如果我们修改代码对其他业务造成影响怎么办?
所以,一个好的设计思路就应该在不改变原代码的基础上实现我们想要的功能。
那么,接下来就应该转变思维,考虑一下,目前的控制权在业务层,所以每次用户需求改变时,业务层也要跟着改变,既然这样,我们把控制权交给用户不就行了吗?
下面来修改一下业务层的代码实现控制权的转换,
public class UserService {
private Fruit fruit;
public void setFruit(Fruit fruit) {
this.fruit = fruit;
}
public void getFruit() {
this.fruit.get();
}
}
细心的同学应该可以看得出改变,我在加了一个set方法,使得用户层可以注入不同的对象,这样我们在用户层传入哪个对象,就会获得哪个结果,
// 1. 获取橘子
public class User {
public static void main(String[] args) {
UserService user = new UsUserServiceerImpl();
user.setFruit(new Orange()); //在这里注入对象
user.getFruit();
}
}
//2. 获取香蕉
public class User {
public static void main(String[] args) {
UserService user = new UserService();
user.setFruit(new Banana());
user.getFruit();
}
}
现在来总结一下,经过改变前后到底发生了什么,
上图展示的很明确,就是控制权的反转,之前主动权在业务层,每次用户提出需求业务层就需要跟着做出改变,现在我们把主动权交给了用户,它传进什么,就得到什么样的结果,这样业务代码就不用跟着改变了。
这就是IOC(控制反转)的核心思想。
优点
控制反转有很多优点,这里我就举例子介绍其中一点。
一个版本发布至少要经历以下几个过程(以镜像化部署为力),
- 合入代码
- 代码规范和安全检查
- 构建成docker镜像
- 启动任务
- alpha测试
- beta测试
- gamma测试
……
试想一下,如果控制权在业务层(程序员手中),那么每次用户需求改变,我们都要经历这样一个繁琐的流程,需要耗费大量的时间和经历。
把控制权反转一下,交出去就不一样了,我们暴露出一个配置文件给用户,用户需要做什么改变,他之间修改配置文件即可,代码不需要跟随改动,这样就没必要再走一遍繁琐的版本发布流程。
以上内容都是我自己的一些感想,分享出来欢迎大家指正,顺便求一波关注,有想法的伙伴可以评论或者私信我哦~
作者:Jackpop
链接:https://www.zhihu.com/question/263455094/answer/1046650888
来源:知乎