我试图在工作中引入依赖注入(DI)模式,我们的一位主要开发人员想知道:如果有的话,使用依赖注入模式的缺点是什么?

注意,如果可能的话,我在这里寻找一个详尽的列表,而不是关于这个主题的主观讨论。


澄清:我谈论的是依赖注入模式(参见Martin Fowler的这篇文章),而不是特定的框架,无论是基于xml的(如Spring)还是基于代码的(如Guice),还是“自滚动”的框架。


Reddit的subreddit /r/programming上正在进行一些深入的讨论/咆哮/辩论。


当前回答

我不认为存在这样的列表,但是试着阅读这些文章:

DI会模糊代码(如果你没有使用好的IDE) Bob叔叔认为,误用IoC会导致糟糕的代码。 需要注意过度设计和创造不必要的多功能性。

其他回答

如果您有一个自己开发的解决方案,依赖项就会在构造函数中直接出现。或者作为方法参数,这也不难发现。尽管框架管理的依赖关系,如果走到极端,就会开始变得像魔术一样。

然而,在太多的类中有太多的依赖项是一个明显的标志,说明你的类结构搞砸了。因此,在某种程度上,依赖注入(自行开发或框架管理)可以帮助发现那些可能隐藏在暗处的突出设计问题。


为了更好地说明第二点,这里是本文的一段摘录(原始来源),我完全相信这是构建任何系统的基本问题,而不仅仅是计算机系统。

Suppose you want to design a college campus. You must delegate some of the design to the students and professors, otherwise the Physics building won't work well for the physics people. No architect knows enough about about what physics people need to do it all themselves. But you can't delegate the design of every room to its occupants, because then you'll get a giant pile of rubble. How can you distribute responsibility for design through all levels of a large hierarchy, while still maintaining consistency and harmony of overall design? This is the architectural design problem Alexander is trying to solve, but it's also a fundamental problem of computer systems development.

DI能解决这个问题吗?不。但它确实帮助你清楚地看到,如果你试图把设计每个房间的责任委托给它的居住者。

基于构造函数的依赖注入(没有神奇的“框架”的帮助)是构造OO代码的一种干净而有益的方式。在我所见过的最好的代码库中,经过多年与Martin Fowler的其他前同事的相处,我开始注意到大多数以这种方式编写的优秀类最终都只有一个doSomething方法。

那么,主要的缺点是,一旦您意识到这只是一种笨拙的、冗长的OO方式,将闭包编写为类,以获得函数式编程的好处,那么您编写OO代码的动机就会迅速消失。

依赖注入是一种技术或模式,与任何框架无关。您可以手动连接依赖项。DI帮助您实现SR(单一职责)和SoC(关注点分离)。DI会带来更好的设计。从我的观点和经验来看,没有坏处。就像任何其他模式一样,你可能会弄错或误用它(但在DI的情况下很难)。

如果您使用框架将DI作为原则引入到遗留应用程序中,那么您可能犯的最大错误就是将其误用为服务定位器。DI+框架本身是伟大的,只是让事情变得更好,我看到它!从组织的角度来看,每一个新的过程、技术、模式……都有共同的问题:

你必须训练你的团队 您必须更改您的应用程序(这包括风险)

一般来说,你必须投入时间和金钱,除此之外,没有任何负面影响,真的!

当您不断地使用技术来处理静态类型时,静态类型语言的假定好处似乎大大减少了。我刚刚采访的一家大型Java商店正在用静态代码分析绘制他们的构建依赖关系……它必须解析所有的Spring文件才能有效。

这更像是吹毛求疵。但是依赖注入的一个缺点是,它使开发工具更难推理和导航代码。

具体来说,如果你在代码中控制-单击/命令-单击方法调用,它将带你到接口上的方法声明,而不是具体的实现。

这实际上是松散耦合代码(由接口设计的代码)的缺点,即使不使用依赖注入(即,即使只是使用工厂)也适用。但是依赖注入的出现真正鼓励了松耦合代码的普及,所以我想我应该提到它。

而且,松散耦合代码的好处远远超过这一点,因此我称之为吹毛求疵。尽管我工作了很长时间,知道如果您试图引入依赖注入,可能会遇到这种情况。

事实上,我敢大胆地猜测,对于依赖注入的每一个“缺点”,您都会发现许多优点远远超过它。