什么是依赖注入?
已经发布了几个关于依赖注入的具体问题的问题,比如何时使用它以及它有哪些框架。 然而,
什么是依赖注入以及何时/为什么应该或不应该使用它?
基本上,不是让对象创建一个依赖关系或要求工厂对象为其创建一个对象,而是将所需的依赖关系传递给外部对象,并使其成为别人的问题。 这个“某人”或者是依赖关系图上的对象,或者是构建依赖关系图的依赖注入器(框架)。 我在这里使用的依赖关系是当前对象需要引用的任何其他对象。
依赖注入的一个主要优点是它可以使测试更容易。 假设你有一个在其构造函数中做了如下操作的对象:
public SomeClass() {
myObject = Factory.getObject();
}
当你想要做的是在SomeClass上运行一些单元测试时,这可能很麻烦,特别是如果myObject是复杂的磁盘或网络访问。 所以现在你正在嘲笑myObject,但也以某种方式拦截工厂调用。 硬。 相反,将该对象作为参数传递给构造函数。 现在,您已将问题转移到其他地方,但测试可能变得更容易。 只需制作一个虚拟的myObject并将其传入即可。构造函数现在看起来有点像:
public SomeClass (MyClass myObject) {
this.myObject = myObject;
}
这是依赖注入的一种风格 - 通过构造函数。 有几种机制是可能的。
当不使用依赖注入时(例如在构造函数中做了太多工作的类中),在单元测试中分离组件变得越来越困难。
回到2013年,当我写这个答案时,这是Google测试博客上的一个主题。 这对我来说仍然是最大的优势,因为您可能并不总是需要运行时设计中的额外灵活性(例如,对于服务定位器或类似模式),但您经常需要在测试期间隔离您的类。
到目前为止,我发现的最好的定义是詹姆斯肖尔的一个定义:
“依赖注入”是一个5美分概念的25美元术语。 [...]依赖注入意味着给对象实例变量。 [...]。
Martin Fowler的一篇文章可能也有用。
依赖注入基本上提供了一个对象需要的对象(它的依赖),而不是让它自己构造它们。 这是一种非常有用的测试技术,因为它允许依赖性被嘲弄或被剔除。
通过许多方法(例如构造函数注入或setter注入)可以将依赖关系注入到对象中。 人们甚至可以使用专门的依赖注入框架(例如Spring)来做到这一点,但它们当然不是必需的。 你不需要这些框架来进行依赖注入。 显式实例化和传递对象(依赖关系)与框架注入一样好。
我发现这个有趣的例子是松耦合:
任何应用程序都由许多对象组成,它们彼此协作以执行一些有用的事情。 传统上,每个对象都负责获取自己对其协作的依赖对象(依赖关系)的引用。 这导致高度耦合的类和难以测试的代码。
例如,考虑一个Car
对象。
Car
取决于车轮,发动机,燃料,电池等运行。 传统上,我们定义了这些依赖对象的品牌以及Car
对象的定义。
无依赖注入(DI):
class Car{
private Wheel wh= new NepaliRubberWheel();
private Battery bt= new ExcideBattery();
//The rest
}
在这里, Car
对象负责创建依赖对象。
如果我们想在初始的NepaliRubberWheel()
刺破之后改变它的依赖对象的类型 - 比如说Wheel
? 我们需要用它的新依赖关系重新创建Car对象,如ChineseRubberWheel()
,但只有Car
制造商可以做到这一点。
那么Dependency Injection
对我们有什么作用?
当使用依赖注入时,对象在运行时被赋予它们的依赖关系,而不是编译时间(汽车制造时间)。 所以我们现在可以随时改变Wheel
。 在这里, dependency
( wheel
)可以在运行时注入Car
。
使用依赖注入之后:
在这里,我们在运行时注入 依赖关系 (Wheel和Battery)。 因此术语:依赖注入。
class Car{
private Wheel wh= [Inject an Instance of Wheel (dependency of car) at runtime]
private Battery bt= [Inject an Instance of Battery (dependency of car) at runtime]
Car(Wheel wh,Battery bt) {
this.wh = wh;
this.bt = bt;
}
//Or we can have setters
void setWheel(Wheel wh) {
this.wh = wh;
}
}
来源:了解依赖注入
链接地址: http://www.djcxy.com/p/251.html