控制反转

控制反转(Inversion of Control,缩写为IoC),是 Martin Fowler 教授提出的一种软件设计模式,是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度

其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫依赖查找(Dependency Lookup)。通俗的来理解,就是本来当需要某个类(构造函数)的某个方法时,自己需要主动实例化变为被动,不需要再考虑如何实例化其他依赖的类,只需要依赖注入 。所谓依赖注入就是由 IoC 容器在运行期间,动态地将某种依赖关系注入到对象之中。所以 IoC 和 DI 是从不同的角度的描述的同一件事情,就是通过引入IoC 容器,利用依赖注入的方式,实现对象之间的解耦。

技术描述

Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。

采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。

简单实例

  • 强耦合调用方式

    将 A 调用 B 的对象修改为 C 类的对象,修改的是调用方的代码,所以我们认为代码的调用权在调用方。

  • 基于 IoC(控制反转)的调用方式

    将上图的需求,修改为使用 IoC 的调用代码方式。就是将代码的控制权从调用方修改为被调用方,意味着,代码的调用权转移给被调用方(我们也称为服务方),不用修改调用方的代码,只要修改配置文件就实现对象的切换。

    如下图:将 A 类调用 B 类的对象修改为 C 类的对象,修改的是被调用方的配置文件的代码,所以代码的调用权转移到了被调用方。通过控制反转,我们可以实现增加模块或者移除模块统一由配置文件关联,所以增加或者移除模块配置 XML 配置文件即可。

    我们将代码的调用权(控制权)从调用方转移给被调用方(服务提供方)的设计模式称为控制反转(IoC)。

根据上图可以得出,实现一个 IoC 的框架,必须要解决两个问题:

  1. 被调用方(服务方),在程序启动时就要根据配置文件类以及类与类的关系创建好对象,放在一个容器里面。

  2. 调用方使用一个接口或类的引用(不用使用 new),就可以创建获得对象。

    我们将这种不用 new,而是根据接口或者类的引用就可以从被调用的容器里获得创建的对象的方式称为依赖注入。

    所以 控制反转(IoC)= 依赖注入 + 面向接口的编程思想的实现

    在这里,我们首先抓住一个重点:Spring 之所以可以实现可插拔程序,是实现了不用 new ,使用类或接口就可以获得对象。

参考:

浅析控制反转

IoC(控制反转)的概述