简介
在软件工程中,依赖注入(dependency injection)的意思为,给予调用方它所需要的事物。“依赖”是指可被方法调用的事物。依赖注入形式下,调用方不再直接指使用“依赖”,取而代之是“注入” 。“注入”是指将“依赖”传递给调用方的过程。在“注入”之后,调用方才会调用该“依赖”。传递依赖给调用方,而不是让让调用方直接获得依赖,这个是该设计的根本需求。在编程语言角度下,“调用方”为对象和类,“依赖”为变量。在提供服务的角度下,“调用方”为客户端,“依赖”为服务。
这是维基百科的定义,不是很容易理解。在这篇文章里,让我们更好地理解依赖注入。
在理解它在编程中的含义之前,首先让我们了解一下它的总体含义,这可以帮助我们更好地理解这个概念。
依赖是指依靠某种东西来获得支持。比如我会说我们对手机的依赖程度过高。
在讨论依赖注入之前,我们先理解编程中的依赖是什么意思。
当 class A 使用 class B 的某些功能时,则表示 class A 具有 class B 依赖。
在 Java 中,在使用其他 class 的方法之前,我们首先需要创建那个 class 的对象(即 class A 需要创建一个 class B 实例)。
因此,将创建对象的任务转移给其他 class,并直接使用依赖项的过程,被称为“依赖项注入”。
![1*TF-VdAgPfcD497kAW77Ukg](https://cdn-media-1.freecodecamp.org/images/1*TF-VdAgPfcD497kAW77Ukg.png)
为什么需要使用依赖注入?
假设我们有一个 car class,其中包含各种对象,例如车轮、引擎等。
这里的 car class 负责创建所有依赖对象。现在,如果我们决定将来放弃 MRFWheels,而希望使用 Yokohama 车轮,该怎么办?
我们将需要使用新的 Yokohama 依赖关系来重新创建 car 对象。但是,当使用依赖注入(DI)时,我们可以在运行时更改车轮 wheels(因为可以在运行时而不是在编译时注入依赖项)。
你可以将依赖注入视为代码中的中间人,它负责创建想要的 wheels 对象,并将其提供给car class。
它使 car class 不需要创建车轮 wheels、电池 battery 对象等。
有三种类型的依赖注入:
- 构造函数注入:依赖关系是通过 class 构造器提供的。
- setter 注入:注入程序用客户端的 setter 方法注入依赖项。
- 接口注入:依赖项提供了一个注入方法,该方法将把依赖项注入到传递给它的任何客户端中。客户端必须实现一个接口,该接口的 setter 方法接收依赖。
依赖注入的作用是:
- 创建对象
- 知道哪些类需要那些对象
- 并提供所有这些对象
如果对象有任何更改,则依赖注入会对其进行调查,并且不应影响到使用这些对象的类。这样,如果将来对象发生变化,则依赖注入负责为类提供正确的对象。
控制反转——依赖注入背后的概念
这是指一个类不应静态配置其依赖项,而应由其他一些类从外部进行配置。
这是 S.O.L.I.D 的第五项原则——一类应该依赖于抽象,而不是依赖于具体的东西(简单地说,就是硬编码)。
根据这些原则,一个类应该专注于履行其职责,而不是创建履行这些职责所需的对象。 这就是依赖注入发挥作用的地方:它为类提供了必需的对象。
使用依赖注入的优势
- 帮助进行单元测试。
- 由于依赖关系的初始化是由注入器组件完成的,因此减少了样板代码。
- 扩展应用程序变得更加容易。
- 帮助实现松耦合,这在应用编程中很重要。
使用依赖注入的劣势
- 学习起来有点复杂,如果使用过度会导致管理问题和其他问题。
- 许多编译时错误被推送到运行时。
- 依赖注入框架是通过反射或动态编程实现的。这可能会妨碍 IDE 自动化的使用,例如“查找引用”,“显示调用层次结构”和安全重构。
你可以自己实现依赖项注入,也可以使用第三方库或框架来实现。
实现依赖注入的库和框架
- Spring (Java)
- Google Guice (Java)
- Dagger (Java and Android)
- Castle Windsor (.NET)
- Unity (.NET)
你可以查看下列资源,了解更多关于依赖注入的信息:
Java 依赖注入—— DI 设计模式示例教程 — JournalDev
希望这篇文章能够帮助你理解依赖注入!
如果你喜欢这篇文章,并且想阅读更多精彩文章,请关注我(Bhavya Karia),支持我写作更多文章。
如果你有任何问题或反馈,可以通过 LinkedIn、Twitter、Facebook 联系我。
如果你想在 JavaScript 中应用依赖注入,Jo Surikat 建议你使用他的库:Di-Ninja。
Nicolas Froidure 介绍了另一个可在 JavaScript 应用依赖注入的库:knifecycle。
如果你是一名 PHP 开发者,Gordon Forsythe 推荐你尝试这个库:auryn。
欢迎你把这篇文章分享给更多人!
原文:A quick intro to Dependency Injection: what it is, and when to use it,作者:Bhavya Karia