依赖注入究竟如何减少耦合?

Gur*_*epS 11 dependency-injection

我已经对依赖注入做了很多阅读,但我不知道,它实际上如何减少耦合?

我对DI的类比是所有组件都在容器中注册,因此它们就像在宝箱中一样.要获得一个组件,你显然首先注册它,但那时你将不得不询问宝箱(这就像一个间接层).这是正确的比喻吗?然而,"注射"是如何发生的并不明显(如何适应这种类比?).

谢谢

Eri*_*ing 41

依赖注入(DI)本身并不减少耦合,因为依赖于依赖关系的组件仍然依赖于它的依赖关系.然而,DI 所做的是消除从组件本身找到依赖关系的责任,并将该责任放在其他地方.

依赖于DI的组件在其依赖性方面是完全被动的.组件中没有代码表示"创建此依赖关系的新实例"或"外出并让我获得此依赖关系".通常在组件本身由其他对象创建时,依赖性被赋予(注入)组件.

创建(或要求创建)依赖关系的责任的逆转称为控制反转(IoC).

因此,如果组件不知道如何创建或要求依赖,那么责任在哪里呢?通常在专门为依赖项解析创建的对象中,通常称为IoC容器.在你的比喻中,这是你的"宝箱".IoC容器包含基本上说:"当有人问了说明这个,给他们的其中之一.IoC容器通常可以检查它的要求来创建组件,找出它的依赖关系,并建立他们太多,走在"依赖链"直到解决了所有依赖关系.

思考,注入的重大转变来自于决定*谁会向容器询问组件的依赖性"?没有DI,组件本身会要求容器依赖它.但是,使用DI,责任要求容器"解决"组件的依赖性属于创建使用组件的任何内容.当创建组件时,创建它的任何东西都有责任提供所有依赖项.组件不知道或不关心它们如何是创造,只是他们是.

现在,如果将依赖项定义为具体实现,则组件仍然该特定具体实现紧密耦合,即使它正在被注入.在这种意义上,DI本身不会减少耦合.但是,如果将依赖项定义为接口,则组件不关心或知道具体实现是什么,也不知道它是如何创建的.它仍然依赖于依赖,但它是一个非常松散的耦合.

从这个意义上说,"依赖注入"和"编程到接口"相结合,创建了非常松散耦合,高度灵活的组件.

  • 最后一个关于实际依赖注入的确实令人满意的答案.在DI方面,有很多关于"减少耦合"的喋喋不休,这一点确定了依赖注入究竟取得了什么.(虽然理论上从类中取出创建或查找逻辑,但确实减少了耦合) (2认同)

use*_*133 4

与你的组件在宝箱中的类比一起去:没有依赖注入的系统(比如一个宝物抛光机)必须能够从宝箱中挑选一个物品.它必须具有依赖性的一些知识才能根据当前的背景选择正确的宝藏.因此耦合.

在DI场景中,您的宝贝抛光机根本不需要了解宝箱的存在.它需要知道的是,在某些时候(最好是在创建时),抛光机将被提供(注入)一个实现的对象ITreasure:

interface ITreasure
{
    void PolishMe();
}
Run Code Online (Sandbox Code Playgroud)

因此,您的实施类与您的宝箱分离.