使用依赖注入时是否存在“新”的情况?

时间:2009-02-10 02:49:34

标签: java oop spring dependency-injection guice

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

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

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

6 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:6)

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

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

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

答案 2 :(得分:4)

使用 new 并没有任何问题,例如它在代码段中的显示方式。

考虑想要附加String片段的情况。你为什么要问注射器是否有StringBuilder?

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

答案 3 :(得分:0)

是的,当然。

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

但是,在足够的情况下,您确实知道要实例化的内容,因此不需要DI。

这就像在面向对象语言中调用函数一样:只是因为你可以使用动态绑定,并不意味着你不能使用旧的静态调度(例如,当你将方法分成几个私有操作时)

答案 4 :(得分:0)

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

因此,当DI过度使用时,我会使用'new'并让它滚动。

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

希望这会有所帮助。

答案 5 :(得分:0)

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

但是,在使用持久层时,您将在持久化对象之前实例化它们。例如,在使用Hibernate时,在调用HibernateTemplate上的save之前,将在持久化对象上调用new。