创建新对象和依赖注入之间的区别

时间:2010-08-02 10:31:40

标签: java object dependency-injection

创建新对象和依赖注入有什么区别?请详细解释。

6 个答案:

答案 0 :(得分:18)

嗯,它们不完全可比。您将始终必须通过在某个时刻实例化类来创建新对象。依赖注入还需要创建新对象。

当您想要控制或验证您使用或想要测试的类所使用的实例的行为时,依赖注入确实起作用。 (对于测试驱动开发,依赖注入是除最小示例之外的任何关键)。

假设一个类Holder,它需要一个Handle类的对象。传统的方法是让Holder实例创建并拥有它:

class Holder {
    private Handle myHandle = new Handle();
    public void handleIt() {
        handle.handleIt();
    }
}

Holder实例创建myHandle,并且类外的任何人都无法获得它。在某些情况下,单元测试正在进行,这是一个问题,因为在不创建Handle实例的情况下测试Holder类是不可能的,而Handle实例又可能依赖于许多其他类和实例。这使得测试变得笨拙和麻烦。

通过注入Handle实例,例如在构造函数中,来自外部的人负责创建实例。

class Holder {
    private Handle myHandle;

    public Holder(Handle injectedHandle) {
        myHandle = injectedHandle;
    }

    public void handleIt() {
        handle.handleIt();
    }
}

正如您所看到的,代码几乎相同,而Handle仍然是私有的,但Holder类现在与其外部世界有很多输入,这使得许多事情变得更简单。在测试Holder类时,可以注入模拟或存根对象而不是实例,从而可以验证或控制Holder,其调用者和句柄之间的交互。

实际注射将在其他地方进行,通常是一些“主要”程序。有多个框架可以帮助您在没有编程的情况下实现这一点,但实际上这是“主要”程序中的代码:

...
private Handle myHandle = new Handle(); // Create the instance to inject
private Handler theHandler = new Handler(myHandle); // Inject the handle
...

从本质上讲,注入只不过是一种花哨的set方法。当然,您可以使用它来实现注入机制,而不是像上面的简单示例那样在构造函数中实现。

答案 1 :(得分:16)

那么, 创建一个新对象就像它可以获得的那样 - 你创建了一个所需类的新实例。

依赖注入是一种为您提供所需参考的机制。 想象一个表示数据库连接池的类 - 通常只有该类的一个实例。现在,您需要将该引用分发给使用它的所有类。 这里是依赖注入派上用场的地方 - 通过使用像Eclipse这样的DI框架,您可以定义池的一个实例将被注入到需要它的类中。

您的问题本身并不容易回答,因为无法轻易地比较对象和依赖注入的创建......

答案 2 :(得分:16)

当然两个都是创建对象。不同之处在于谁负责创作。它是需要其依赖项的类还是像Spring这样的容器,它连接组件依赖项。您可以在单独的(通常为XML)配置文件中配置依赖项。

这实际上是一种关注点的分离。该课程说我需要这个,这个和这个组件所以我正常运作。该课程并不关心它如何获得它的组件。您可以使用单独的配置文件将它们插入到类中。

举个例子,让我们考虑购买一个需要支付模块的购物课程。您不想硬编码将使用哪个付款模块。为实现此目的,您可以反转控件。您可以在容器的配置文件中通过几次击键来更改使用的付款模块。权力是你没有接触任何Java代码。

答案 3 :(得分:3)

依赖注入为您的应用程序添加了一层可配置性。从某种意义上说,当你硬编码对象构建时,你需要重新构建和重新部署你的应用程序,但是当你使用依赖注入时,你可以重新配置XML并改变行为而无需重新构建和重新部署。有很多种用例可以节省大量的工作和精力。

答案 4 :(得分:2)

使用反转控件容器执行依赖项注入时,容器会创建对象,而不是开发人员。这样做是为了使容器可以将这些对象“注入”到其他对象中。

我建议你阅读一些关于依赖注入和/或弹簧的文章。或者在SO上阅读有关依赖注入的其他主题。

答案 5 :(得分:0)

以下问题的答案也可能会为您提供所需的答案:为什么新运算符是反模式?好吧,简单的答案是,使用new运算符可能会在包含的类中创建一个隐藏的,不可访问的依赖关系。这使得测试包含类变得更加困难,因为它涉及同时测试隐藏的依赖关系(当然不包括MOCK框架)。但是,可以通过不使用new运算符并注入依赖对象来避免这种情况。这也具有以下优点:

  • 出于测试目的,您可以注入其他对象。
  • 生成的包含类更可重用,因为它可以支持依赖对象的不同实现。