一篇文章教你理解控制反转(IoC)与依赖注入(DI)

什么是控制反转?


软件中的对象就像齿轮一样,协同工作、互相耦合。若有一个零件不能工作,便会导致整个系统的崩溃。这种系统称为强耦合系统。
齿轮组中齿轮之间的啮合关系与软件系统对象的耦合关系十分相似,对象的耦合是必要的,也是无法避免的,这是协同工作的基础。
随着对象之间的依赖关系越来越复杂,对象之间的多重依赖性关系也随之经常出现。这就对架构师和系统设计师关于系统的分析的设计提出了巨大的挑战。
对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。

为了解决对象间耦合度过高的问题,Michael Mattson提出了IoC理论,用来实现对象之间的“解耦”。

控制反转(Inversion of Control)是一种面向对象编程中的一种设计原则,用来降低代码间的耦合度。其基本思想是:借助于“第三方”实现具有依赖关系的对象间的解耦。

由于引入了第三方loC容器,A、B、C、D四个对象没有了耦合关系,齿轮之间的传动全部依赖于第三方,这样就把loC容器变成了系统的核心,它就像“粘合剂”一样,将A、B、C、D四个对象粘合起来发挥作用。

“控制反转”实际上是变主动为被动的过程

在没有引入loC容器前,对象A在初始化或者运行过程中,必须自己主动去创建或者使用已经创建的对象B,无论创建还是使用,主动权都在A手上。

在引入loC容器后,对象A与B失去了直接联系,当对象A需要对象B时,loC容器会主动创建一个对象B注入到对象A需要的地方,对象A只需要被动接受就可以了。

什么是依赖注入?

依赖注入(Dependency Injection) 常常简称为:DI。它是实现控制反转(Inversion of Control – IoC)的一个模式。

它的本质目的是解耦,保持软件组件之间的松散耦合,为设计开发带来灵活性。

什么是依赖?

如果在 Class A 中,有 Class B 的实例,则称 Class A 对 Class B 有一个依赖。例如下面类 Human 中用到一个 Father 对象,我们就说类 Human 对类 Father 有一个依赖。

public class Human {
    ...
    Father father;
    ...
    public Human() {
        father = new Father();
    }
}

如果现在要改变 father 生成方式,如需要用new Father(String name)初始化 father,需要修改 Human 代码,因为 father 的初始化被写死在了 Human 的构造函数中,影响效率。

依赖注入

public class Human {
    ...
    Father father;
    ...
    public Human(Father father) {
        this.father = father;
    }
}

上面代码中,我们将 father 对象作为构造函数的一个参数传入。在调用 Human 的构造方法之前外部就已经初始化好了 Father 对象。像这种非自己主动初始化依赖,而通过外部来传入依赖的方式,我们就称为依赖注入。

控制反转和依赖注入的关系

我们已经分别解释了控制反转和依赖注入的概念。有些人会把控制反转和依赖注入等同,但实际上它们有着本质上的不同。

控制反转是一种思想
依赖注入是一种设计模式

发布了72 篇原创文章 · 获赞 81 · 访问量 7437

猜你喜欢

转载自blog.csdn.net/weixin_43332735/article/details/104497405