【问题标题】:Is there ever a case for 'new' when using dependency injection?使用依赖注入时是否有“新”的情况?
【发布时间】:2010-10-06 13:35:15
【问题描述】:

依赖注入是否意味着你永远不需要'new'关键字?还是直接创建集合等简单的叶子类合理吗?

在下面的例子中我注入了比较器、查询和dao,但是SortedSet是直接实例化的:

public Iterable<Employee> getRecentHires()
{
    SortedSet<Employee> entries = new TreeSet<Employee>(comparator);
    entries.addAll(employeeDao.findAll(query));
    return entries;
}

【问题讨论】:

    标签: java oop spring dependency-injection guice


    【解决方案1】:

    仅仅因为依赖注入是一种有用的模式并不意味着我们可以将它用于所有事情。即使在使用 DI 时,也经常需要 new。暂时不要删除新的。

    【讨论】:

      【解决方案2】:

      我通常决定是否使用依赖注入的一种方法是在为被测类编写单元测试时是否需要模拟或存根协作类。例如,在您的示例中,您(正确地)正在注入 DAO,因为如果您为您的类编写单元测试,您可能不希望任何数据实际写入数据库。或者可能是一个协作类将文件写入文件系统或依赖于外部资源。或者行为是不可预测的或难以在单元测试中解释。在这些情况下,最好注入这些依赖项。

      对于像 TreeSet 这样的协作类,我通常不会注入它们,因为通常不需要模拟这些简单的类。

      最后一点:当一个字段由于某种原因无法注入,但我仍然想在测试中模拟它时,我发现Junit-addons PrivateAccessor 类有助于将类的私有字段切换为由EasyMock(或 jMock 或您喜欢的任何其他模拟框架)创建的模拟对象。

      【讨论】:

      • Spring 也有 ReflectionTestUtils 类用于私有成员的操作。
      【解决方案3】:

      使用 new 并没有什么问题,就像它在您的代码 sn-p 中显示的那样。

      考虑想要附加字符串 sn-ps 的情况。为什么要向注入器询问 StringBuilder ?

      在我遇到的另一种情况下,我需要根据容器的生命周期运行一个线程。在这种情况下,我必须执行 new Thread(),因为我的 Injector 是在调用容器启动的回调方法之后创建的。一旦注入器准备就绪,我将一些托管类手动注入到我的 Thread 子类中。

      【讨论】:

        【解决方案4】:

        是的,当然。

        依赖注入适用于客户端可能不知道(或无法做出选择)编译时间的多个可能的实例化目标的情况。

        但是,在很多情况下,您确实知道要实例化什么,因此不需要 DI。

        这就像在面向对象语言中调用函数:仅仅因为您可以使用动态绑定,并不意味着您不能使用好的旧静态调度(例如,当您将方法拆分为多个私有操作时) .

        【讨论】:

          【解决方案5】:

          我的想法是,DI 非常棒,非常适合连接层以及需要灵活应对潜在变化的代码片段。当然我们可以说一切都可能需要改变,但我们都知道在实践中有些东西是不会被触及的。

          因此,当 DI 过于矫枉过正时,我会使用“新”并让它滚动。

          例如:对我来说,将模型连接到视图到控制器层.. 它总是通过 DI 完成。我的应用程序使用的任何算法,DI 以及任何可插入的反射代码,DI。数据库层.. DI,但我的系统中使用的几乎所有其他对象都是用一个常见的“新”处理的。

          希望这会有所帮助。

          【讨论】:

            【解决方案6】:

            确实,在当今框架驱动的环境中,实例化对象越来越少。例如,Servlet 由 servlet 容器实例化,Spring 中的 bean 由 Spring 实例化等。

            不过,当使用持久层时,您将在持久化对象被持久化之前对其进行实例化。例如,在使用 Hibernate 时,您将在持久化对象上调用 new,然后在 HibernateTemplate 上调用 save。

            【讨论】:

              猜你喜欢
              • 2020-12-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-12-17
              相关资源
              最近更新 更多