我试图在工作中引入依赖注入(DI)模式,我们的一位主要开发人员想知道:如果有的话,使用依赖注入模式的缺点是什么?
注意,如果可能的话,我在这里寻找一个详尽的列表,而不是关于这个主题的主观讨论。
澄清:我谈论的是依赖注入模式(参见Martin Fowler的这篇文章),而不是特定的框架,无论是基于xml的(如Spring)还是基于代码的(如Guice),还是“自滚动”的框架。
Reddit的subreddit /r/programming上正在进行一些深入的讨论/咆哮/辩论。
我试图在工作中引入依赖注入(DI)模式,我们的一位主要开发人员想知道:如果有的话,使用依赖注入模式的缺点是什么?
注意,如果可能的话,我在这里寻找一个详尽的列表,而不是关于这个主题的主观讨论。
澄清:我谈论的是依赖注入模式(参见Martin Fowler的这篇文章),而不是特定的框架,无论是基于xml的(如Spring)还是基于代码的(如Guice),还是“自滚动”的框架。
Reddit的subreddit /r/programming上正在进行一些深入的讨论/咆哮/辩论。
当前回答
以下几点:
DI增加了复杂性,通常是通过增加类的数量,因为责任分离得更多,这并不总是有益的 您的代码将(在某种程度上)耦合到您使用的依赖注入框架(或者更一般地说,如何决定实现DI模式) 执行类型解析的DI容器或方法通常会导致轻微的运行时损失(非常可以忽略不计,但它确实存在)
通常,解耦的好处是使每个任务更易于阅读和理解,但增加了编排更复杂任务的复杂性。
其他回答
它可以增加应用启动时间,因为IoC容器应该以适当的方式解析依赖关系,有时需要进行多次迭代。
代码可读性。由于依赖关系隐藏在XML文件中,因此您无法轻松地找出代码流。
没有任何DI的代码会面临众所周知的陷入意大利面条代码的风险——一些症状是类和方法太大,做太多,不容易更改、分解、重构或测试。
大量使用DI的代码可以是Ravioli代码,其中每个小类就像一个单独的Ravioli块——它只做一件小事,并且遵循单一责任原则,这是很好的。但是从类本身来看,很难看到系统作为一个整体在做什么,因为这取决于所有这些小部分是如何组合在一起的,这是很难看到的。它看起来就像一大堆小东西。
通过避免大型类中大量耦合代码的意大利面复杂性,您将面临另一种复杂性的风险,其中有许多简单的小类,它们之间的交互非常复杂。
我不认为这是一个致命的缺点- DI仍然是非常值得的。在某种程度上,小班级只做一件事的馄饨风格可能是好的。即使过度,我也不认为它像意大利面条代码那样糟糕。但是要避免它,第一步是要意识到它可能会走得太远。点击链接了解如何避免这种情况。
基于构造函数的依赖注入(没有神奇的“框架”的帮助)是构造OO代码的一种干净而有益的方式。在我所见过的最好的代码库中,经过多年与Martin Fowler的其他前同事的相处,我开始注意到大多数以这种方式编写的优秀类最终都只有一个doSomething方法。
那么,主要的缺点是,一旦您意识到这只是一种笨拙的、冗长的OO方式,将闭包编写为类,以获得函数式编程的好处,那么您编写OO代码的动机就会迅速消失。
我不认为存在这样的列表,但是试着阅读这些文章:
DI会模糊代码(如果你没有使用好的IDE) Bob叔叔认为,误用IoC会导致糟糕的代码。 需要注意过度设计和创造不必要的多功能性。