尽管它很流行,但是是否有任何经验证据表明依赖注入(和/或使用DI容器)有助于例如减少错误计数,提高可维护性或提高现实软件项目的开发速度?
尽管它很流行,但是是否有任何经验证据表明依赖注入(和/或使用DI容器)有助于例如减少错误计数,提高可维护性或提高现实软件项目的开发速度?
Answers:
经验数据无关紧要。工具和实践(例如DI)可以解决特定问题。了解您的问题,学习如何使用这些工具,当一个工具有价值时,它将变得很明显- 并且您将比任何广义的,汇总的,经验性的数据更能预言性地解释结果。
现在,有了更多的冗长...
当然可以。或者至少是。但谁在乎?这无关紧要。
DI的统计成本效益分析在学术上可能很有趣,但不一定能预测个人成功。汇总结果隐藏了个人的成功和失败。而且,我可能会争辩说,有关“福音”实践的数据特别有毒。这些纪律往往会吸引狂热者和傻瓜,这两者都掩盖了“纯”实施的净影响,而您可能两者都是!
好问题!实际上,很棒的问题。我支持您-我讨厌浪费时间和精力在教条主义的“最佳实践”上,没人能证明。所以,很高兴你问。
嗯 但是,这是一个令人尴尬的问题…… 总的来说,您不知道。而且,更令人尴尬的是,通过引入DI,您的代码实际上可能不会以任何方式变得更好。
喘气!
⊙▃⊙ . . . (╯°□°)╯︵ ┻━┻
...
所以,也许现在你在想...
首先,在辩论的每个方面,让我们都安顿下来。我可以向您保证,在教条主义和怀疑论之间,存在着一个美丽的理性和头脑冷静的天堂。(还有偶尔出现的古怪的SE.SE帖子。)而且,POAP可以带您到达那里。
...我指的是适用原则:
原则,模式和实践不是最终目的。因此,每种方法的良好和正确应用都会受到更高,更最终的目的的启发和约束。
您需要了解为什么要做自己在做的事情!
(POAP不受POAP的限制。)
(我想说的是“强调我的”,但这还是来自我自己的“博客”。所以,这全都是我的!)
让我重申这里的要点:您需要了解为什么要执行自己的操作。
也许需要澄清的是,采取任何给定的“东西”(例如“依赖注入”)通常是没有意义的,而在没有了解要解决的问题的情况下使用它(特别是针对您)。如果您了解自己的问题以及“某物”(如DI)的工作原理,那么“某物”的帮助将在某种程度上“显而易见”,而无论广义,汇总,经验数据的含义如何。
如果DI 对您的帮助或不帮助不是很明显-或至少超出了您的推理能力-您要么不了解DI,要么不了解自己的问题。
让我们考虑一个现实世界中的“寓言”。
我们需要构造一个盒子。我们有木头。我们有指甲。并且,我们有两种工具:标准的羊角锤和螺丝刀。
现在,我们可能有一些广泛的经验数据表明,与用锤子建造的那些盒子相比,用螺丝刀建造的盒子总体上更坚固。但是,如果您试图将那些钉子拧进去,那么最终将根本没有盒子。而且,如果尝试用螺丝刀敲击它们,则最终可能会将它们插入。但是,这将需要更多的时间和精力,并且最终结果将比仅使用锤子的精度(和鲁棒性)低。
而且,如果您曾经见过有人使用过任何一种工具,并且了解了盒子的外观,那么决定就显而易见了。
心灵感应!
嗯...嗯...
它可以防止僵化的,不可配置的代码,而这些代码通常是无法测试的。
它通过允许调用代码来确定模块使用哪些对象来实现此目的。我知道您在想,您是对的:这甚至不是一个遥不可及的新概念。自代数发生以来,方法/功能参数一直存在。
一旦我们积累并继承了足够多的代码以查看我们的不平衡状态,我们便开始传播基本参数传递,称为“依赖注入”。仅仅因为依赖关系被隐藏起来,我们就无法轻易地更改,测试甚至重用我们坐在上面的大量代码。
因此,对依赖注入的热心十字军...
据我了解,DI 框架主要解决了样板增加的问题(由于过分的DI和IMO)-尤其是当所有需要它们的模块都有标准的“默认”依赖项时。当在调用点未显式传递默认依赖项时,DI框架会做一些神奇的事情(甚至可能很顽皮!)。(以这种方式使用时,与服务定位器的效果相同,请注意!)
依赖注入作为“学科”,实际上真的很难解决。是否使用DI都不是问题。要知道哪些依赖项可能会更改或需要模拟并注入这些依赖关系。然后,要确定DI是否比某些替代方法(例如服务位置)更适合自己。
但是,我鼓励您使用Google,可能会看到这样的答案,可能会与您行业中经验丰富且成功的开发人员交谈,并将特定示例发布到CR.SE上。
我搜索了Google,Google Scholar,ACM和IEEE,以下是我能够找到的论文:
依赖注入框架:可测试性的改进?。它认为“可测试性”可以定义为“低内聚性”。它指出,DI导致较低的内聚力,较低的内聚力与较高的测试覆盖率相关,而较高的测试覆盖率与发现的更多故障相关。它说,基于此,DI提高了可测试性。
我不喜欢这样做有几个原因。首先,这是说“ A与B相关联,B与C相关联,因此A导致C”,这是我认为在逻辑上没有得到很好支持的几个步骤。其次,它承认它只是在测量“可测试性的各个部分”,而“可测试性”通常很难定义。最后,它们的可测试性度量是根据注入的依赖项的数量定义的!
依赖注入对可维护性的影响。他们将使用DI的项目与在SourceForge上发现的不使用DI的项目进行比较,并查看内聚度指标是否存在差异。为了减少偏差,他们将项目配对为尽可能相似的项目。最终,他们看到了信号,即具有大量DI的项目与具有少量DI的项目相比耦合程度较小。但是,DI项目与其非DI对之间的内聚性似乎没有显着差异,因此这可能是特定领域的结果。他们将“没有相关性”列为主要结果,而“也许有一点帮助?” 作为进一步研究的主题。
根据经验评估依赖注入对Web服务应用程序开发的影响。摘要并没有真正解释他们在寻找什么。我挖了一个预印本,据我所知,这实际上是关于自动化工具如何很好地发现服务。以DI风格编写的服务更容易发现。而且,它引用了我列出的先前的研究,作为经验证据表明DI减少了耦合,这与该论文所声称的相反。
对于这三篇论文(以及关于Java中依赖注入的使用的实证研究(仅与检测有关)),我都引用了所有引用它们的论文,但这些论文都与确定DI的有效性无关。鉴于这一切,我有信心说,不,我们还没有对DI是否提高软件质量的经验证据。