17

依赖注入是否意味着您永远不需要“新”关键字?或者直接创建简单的叶子类比如集合是否合理?

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

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

6 回答 6

10

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

于 2009-02-10T02:52:28.933 回答
7

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

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

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

于 2009-02-10T03:44:07.983 回答
4

使用new并没有错,就像它在代码片段中的显示方式一样。

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

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

于 2009-02-10T03:04:17.673 回答
0

是的当然。

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

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

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

于 2009-02-10T02:56:42.620 回答
0

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

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

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

希望这可以帮助。

于 2009-02-16T01:44:46.593 回答
0

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

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

于 2009-02-21T00:57:55.540 回答