我先自己总结一下
IOC: 原来上层依赖下层,下层改变,上层也要大量的修改,不好.所以上层中拿着下层的对象,下层改变不影响上层.
DI: 上层持有下层对象,每次都要new,依赖传递下去,new一个上层对象,结果可能要依赖几十个对象.太麻烦,所以spring帮我们做了控制反转,new你要的对象就行,其他的不用你管.它的实现就是:你要一个car,在创建car的时候发现car需要依赖框架frame,好,再创建一个frame,啊,创建frame需要底盘?行,给你创建个底盘,创建底盘时发现还需要轮胎,好再给你new 轮胎.new轮胎的时候,终于没有依赖了.好,再反向的组装起来,最后给你一个car.
好了,以下是原文
要了解控制反转( Inversion of Control ), 我觉得有必要先了解软件设计的一个重要思想:依赖倒置原则(Dependency Inversion Principle )。
我们现在换一种思路。我们先设计汽车的大概样子,然后根据汽车的样子来设计车身,根据车身来设计底盘,最后根据底盘来设计轮子。这时候,依赖关系就倒置过来了:轮子依赖底盘, 底盘依赖车身, 车身依赖汽车。
这就是依赖倒置原则——把原本的高层建筑依赖底层建筑“倒置”过来,变成底层建筑依赖高层建筑。高层建筑决定需要什么,底层去实现这样的需求,但是高层并不用管底层是怎么实现的。这样就不会出现前面的“牵一发动全身”的情况。
所以我们需要进行控制反转(IoC),及上层控制下层,而不是下层控制着上层。我们用依赖注入(Dependency Injection)这种方式来实现控制反转。所谓依赖注入,就是把底层类作为参数传入上层类,实现上层类对下层类的“控制”。这里我们用构造方法传递的依赖注入方式重新写车类的定义:
这里我们是采用的构造函数传入的方式进行的依赖注入。其实还有另外两种方法:Setter传递和接口传递。这里就不多讲了,核心思路都是一样的,都是为了实现控制反转。
IoC Container的第二个好处是:我们在创建实例的时候不需要了解其中的细节。在上面的例子中,我们自己手动创建一个车instance时候,是从底层往上层new的:
而IoC Container在进行这个工作的时候是反过来的,它先从最上层开始往下找依赖关系,到达最底层之后再往上一步一步new(有点像深度优先遍历):
实际项目中,有的Service Class可能是十年前写的,有几百个类作为它的底层。假设我们新写的一个API需要实例化这个Service,我们总不可能回头去搞清楚这几百个类的构造函数吧?IoC Container的这个特性就很完美的解决了这类问题,大大增加了项目的可维护性且降低了开发难度。
作者:Sevenvidia链接:https://www.zhihu.com/question/23277575/answer/169698662来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。