什么是依赖注入? [英] What is dependency injection?

查看:331
本文介绍了什么是依赖注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已经有几个问题已经发布,有关依赖注入的特定问题,例如何时使用它和它的框架。但是,

There have been several questions already posted with specific questions about dependency injection, such as when to use it and what frameworks are there for it. However,

什么是依赖注入,何时/为什么应该或不应该使用它?

推荐答案

基本上,不是让对象创建一个依赖关系或者要求一个工厂对象为它们创建一个对象,而是将所需的依赖关系传递给外部的对象,而你使其他人的问题。这个某人是依赖图上的一个对象,还是构建依赖图的依赖注入器(框架)。我在这里使用的依赖关系是当前对象需要持有引用的任何其他对象。

Basically, instead of having your objects creating a dependency or asking a factory object to make one for them, you pass the needed dependencies in to the object externally, and you make it somebody else's problem. This "someone" is either an object further up the dependency graph, or a dependency injector (framework) that builds the dependency graph. A dependency as I'm using it here is any other object the current object needs to hold a reference to.

依赖注入的一个主要优点是它可以使测试更容易。假设你有一个对象,在它的构造函数中做一些类似的东西:

One of the major advantages of dependency injection is that it can make testing lots easier. Suppose you have an object which in its constructor does something like:

public SomeClass() {
    myObject = Factory.getObject();
}

当您想做的只是运行一些单元测试时,这可能很麻烦SomeClass,特别是如果myObject是复杂的磁盘或网络访问。所以现在你正在嘲笑我的对象,但也以某种方式拦截工厂调用。硬。相反,将对象作为参数传递给构造函数。现在,您已将问题转移到其他地方,但是测试可能会变得更加容易。只是做一个虚拟的myObject并传递给它。构造函数现在看起来有点像:

This can be troublesome when all you want to do is run some unit tests on SomeClass, especially if myObject is something that does complex disk or network access. So now you're looking at mocking myObject but also somehow intercepting the factory call. Hard. Instead, pass the object in as an argument to the constructor. Now you've moved the problem elsewhere, but testing can become lots easier. Just make a dummy myObject and pass that in. The constructor would now look a bit like:

public SomeClass (MyClass myObject) {
    this.myObject = myObject;
}

这是依赖注入的一种风格 - 通过构造函数。几种机制是可能的。如注释所述,一个常见的替代方法是定义一个do-nothing构造函数,并通过属性设置器(h / t @MikeVella)注入依赖关系。 Martin Fowler 记录了第三种替代方案(h / t @MarcDix),其中类明确实现接口为他们希望注入的依赖关系。

This is one style of dependency injection - via the constructor. Several mechanisms are possible. As noted in the comments, one common alternative is to define a do-nothing constructor, and have the dependencies injected via property setters (h/t @MikeVella). Martin Fowler documents a third alternative (h/t @MarcDix), where classes explicitly implement an interface for the dependencies they wish injected.

当不使用依赖注入(例如在类中在构造函数中做太多工作等)时,它往往会变得很多在单元测试中更难隔离组件。早在2013年,当我写了这个答案时,这是 Google测试博客的主题。这仍然是我最大的优势,因为您可能并不总是需要运行时设计(例如,服务定位器或类似模式)的额外灵活性,但是您经常需要在测试期间隔离您的类。

When not using dependency injection (such as in classes that do too much work in their constructors etc.), it tends to become much harder to isolate components in unit testing. Back in 2013 when I wrote this answer, this was a major theme on the Google Testing Blog. This remains the biggest advantage to me, as you may not always need the extra flexibility in your run-time design (for instance, for service locator or similar patterns), but you do often need to be able to isolate your classes during testing.

这篇关于什么是依赖注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆