【问题标题】:What is Inversion of Control? How does that relate to dependency injection? [duplicate]什么是控制反转?这与依赖注入有什么关系? [复制]
【发布时间】:2011-02-18 03:22:20
【问题描述】:

可能的重复:
Difference between Dependency Injection (DI) & Inversion of Control (IOC)
Inversion of Control < Dependency Injection

嘿,这是Scott Hanselman interview question。我总是觉得这个问题很难回答。 可能这个问题的一部分可以在堆栈上回答,但总的来说这非常重要。

我还想知道除 DI 之外的其他形式的 IoC。

谁能用一些实时的例子来解释我。

谢谢

【问题讨论】:

  • @duffymo, @Robert Harvey,对不起,他们不是。
  • @duffymo 不,它们根本不一样,它们只是倾向于一起使用。面试问题的重点是弄清楚谁真正知道他们是什么,因为他们很常用,而且通常很难理解。也因为面试官喜欢迂腐:-)
  • 不仅迂腐,而且误导。来自(Dependency Injection Prasanna2009)“控制反转这一短语相当模糊,意味着职责的普遍颠倒,这是非特定的......在通常使用中,依赖注入器经常被称为 IoC 容器。为了清楚起见,对于在本书的其余部分,我将放弃 IoC 及其邪恶的表亲 IoC 容器这一术语。”

标签: design-patterns dependency-injection inversion-of-control


【解决方案1】:

依赖注入不是 IoC 的一种形式。控制反转是一种与 DI 完全无关的模式,只是它们通常在某种框架中一起使用,这导致人们认为它们是同一事物,而实际上并非如此。

依赖注入只是意味着您通过构造函数或一系列setter将类的依赖注入到其中,而不是在类中实例化它们。它可以在没有任何类型的 IoC 容器的情况下完全手动完成。

手动 DI 的一个非常简单的例子可能是:

import org.apache.http.client.HttpClient;


public class TwitterClient {

    private HttpClient httpClient;

    public TwitterClient(HttpClient httpClient){
        this.httpClient = httpClient;
    }
}

每当您在代码中创建 TwitterClient 时,您还必须创建一个 HttpClient 并将其传入。由于这会相当乏味,因此有一些框架可以使其更容易,但正如我所提到的,完全有可能做到这一点手动。本文涉及手动 DI - http://googletesting.blogspot.com/2009/01/when-to-use-dependency-injection.html,事实上,一些 Google 产品的早期版本完全围绕手动 DI 构建。

这里的好处是您可以交换实现,因此如果您想传入一个存根的客户端以进行单元测试,这很容易。否则,就没有真正的方法来对这样的类进行单元测试。

IoC 意味着您拥有某种框架来控制应用程序的生命周期。不涉及 DI 的 IoC 的一个很好的例子就是任何 Cocoa 苹果框架,它控制 Cocoa 应用程序的生命周期。您实现了在应用程序生命周期中的某些点被调用的某些方法。这就是为什么它是“好莱坞原则”,你不调用框架,框架调用你。

【讨论】:

  • 您能否用 .net 或 java 术语解释一下 IoC。我不熟悉 Apple 框架。
  • 这是一个非常笼统的概念。这意味着您部署代码的框架可以控制该代码的生命周期,而不是您的代码控制自己的生命周期。
  • 可能最简单的示例是将 servlet 部署到 Tomcat 之类的容器中。在这种情况下,容器负责创建和初始化您的应用程序,并控制哪些应用程序处理哪些请求。应用容器可能不是人们认为的 IoC,但它是......
  • 我不会说 DI 与 IoC完全无关。 IoC 使用 DI 来实现其目标。而且 IoC 不需要框架。
  • @Robert Harvey IoC 不需要使用 DI。时期。句号。大多数时候,它没有。它在 Spring 和类 Spring 框架中一起使用,因此人们经常将两者混为一谈。它们是两个独立的东西这一事实是这样的面试问题的重点(可能更多是因为它很容易问,而不是因为它显示了实际有用的知识)。我第一次遇到这个术语是在 Martin Fowler 的网站上 -martinfowler.com/bliki/InversionOfControl.html,他的示例实际上依赖于一个窗口工具包,在任何地方都没有引用 DI。
【解决方案2】:

对于面试,我会简短地说控制反转是通过将执行顺序与正在执行的实际业务规则分开来将组件彼此分离的能力。一个例子是在一个 MVC 应用程序中,一个调用多个控制器的视图,并不关心控制器会做什么,而是控制它们执行的顺序。

依赖注入是使用接口在类之间调用,并且只有在运行时才会指定实际的类(例如在配置 XML 文件中)。 DI 允许在更细粒度的级别上进行测试。它通过将错误与测试隔离开来帮助维护。

它们的相似之处在于依赖注入使用控制反转来允许代码调用接口而不关心实际的实现类,只关心接口。依赖注入允许(从示例中)视图控制接口调用的顺序,而无需关心实际使用哪个类。

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 1970-01-01
    • 2011-02-08
    • 2011-03-14
    • 1970-01-01
    • 2010-11-24
    相关资源
    最近更新 更多