Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 使用依赖注入的缺点是什么?_Design Patterns_Dependency Injection - Fatal编程技术网

Design patterns 使用依赖注入的缺点是什么?

Design patterns 使用依赖注入的缺点是什么?,design-patterns,dependency-injection,Design Patterns,Dependency Injection,我试图将DI作为一种模式引入工作中,我们的一位主要开发人员想知道:使用依赖注入模式的缺点是什么 请注意,我在这里寻找一个——如果可能的话——详尽的列表,而不是关于这个主题的主观讨论 澄清:我说的是依赖注入模式(见Martin Fowler),而不是一个特定的框架,无论是基于XML(如Spring)还是基于代码(如Guice)还是“自滚式” 编辑:这里正在进行进一步的讨论/咆哮/辩论 我自己的初步反应是:基本上任何模式都有相同的缺点 学习需要时间 如果被误解,可能弊大于利 如果把它发挥到极致

我试图将DI作为一种模式引入工作中,我们的一位主要开发人员想知道:使用依赖注入模式的缺点是什么

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


澄清:我说的是依赖注入模式(见Martin Fowler),而不是一个特定的框架,无论是基于XML(如Spring)还是基于代码(如Guice)还是“自滚式”



编辑:这里正在进行进一步的讨论/咆哮/辩论

我自己的初步反应是:基本上任何模式都有相同的缺点

  • 学习需要时间
  • 如果被误解,可能弊大于利
  • 如果把它发挥到极致,它可能会比证明其好处的工作更多

代码可读性。由于依赖项隐藏在XML文件中,因此您将无法轻松了解代码流

有两点:

  • DI增加了复杂性,通常是通过增加类的数量来实现的,因为职责分离得更多,这并不总是有益的
  • 您的代码将(在某种程度上)耦合到您使用的依赖注入框架(或者更一般地说,您决定如何实现DI模式)
  • 执行类型解析的DI容器或方法通常会产生轻微的运行时惩罚(可以忽略不计,但确实存在)

通常,解耦的好处是使每个任务更易于阅读和理解,但会增加编排更复杂任务的复杂性。

如果您有一个自主开发的解决方案,那么在构造函数中,依赖关系就在您面前。或者作为方法参数,同样也不难发现。尽管框架管理的依赖关系,如果走到极端,可能会开始像魔术一样出现

然而,在太多的类中有太多的依赖项是一个明显的迹象,表明您的类结构是错误的。因此,在某种程度上,依赖项注入(自主开发或框架管理)有助于解决隐藏在黑暗中的突出设计问题


为了更好地说明第二点,这里有一段摘自()的内容,我衷心相信这是构建任何系统的根本问题,而不仅仅是计算机系统

假设你想设计一个大学校园。你必须把一些设计委托给学生和教授,否则物理大楼对物理专业的人来说就不好用了。没有一个架构师足够了解人们自己需要做什么。但是你不能把每个房间的设计都委托给它的居住者,因为那样你会得到一大堆瓦砾

如何在保持整体设计的一致性和协调性的同时,将设计责任分配到大型层次结构的所有级别?这是亚历山大试图解决的建筑设计问题,但也是计算机系统开发的一个基本问题


DI解决了这个问题吗。但是,如果你试图将设计每个房间的责任委托给居住者,这确实有助于你清楚地看到。我认为不存在这样的列表,但是请阅读以下文章:


它可以增加应用程序的启动时间,因为IoC容器应该以适当的方式解决依赖关系,有时需要进行多次迭代。

如果您在没有IoC容器的情况下使用DI,最大的缺点是您可以很快看到您的代码实际上有多少依赖关系,以及所有内容之间的紧密耦合程度。(“但我认为这是一个很好的设计!”)自然的进展是朝着一个IOC容器的方向发展,这个容器需要花费一点时间来学习和实现(虽然没有WPF学习曲线那么糟糕,但也不是免费的)。最后一个缺点是,一些开发人员将开始编写诚实的单元测试,这将需要他们花时间来解决。以前可以在半天内完成某项工作的开发人员会突然花上两天的时间来尝试如何模拟他们所有的依赖关系


与Mark Seemann的回答类似,底线是你要花时间成为一名更好的开发人员,而不是把代码拼凑在一起,然后扔出大门/投入生产。您的企业更愿意选择哪一种?只有你能回答这个问题。

控制反转最大的“缺点”(不完全是DI,但足够接近)是,它倾向于去掉单一点来查看算法概述。不过,这基本上就是当您使用解耦的代码时会发生的情况-在一个地方查看的能力是紧密耦合的产物。

我发现构造函数注入可能会导致大而丑陋的构造函数(我在整个代码库中都使用它-也许我的对象太细粒度了?)。此外,有时构造函数注入会导致可怕的循环依赖(尽管这是非常罕见的),因此您可能会发现自己必须在更复杂的系统中进行几轮依赖注入,从而获得某种就绪状态生命周期

然而,我更喜欢construtor注入而不是setter注入,因为一旦构建了我的对象,我就毫无疑问地知道它处于什么状态,不管它是在单元测试环境中还是加载在某个IOC容器中。以一种迂回的方式,我认为这是塞特注射的主要缺点


(作为旁注,我确实觉得整个主题非常“宗教化”,但您的里程数将随开发团队的技术狂热程度而变化!)

DI是一种技术或模式,与任何框架都不相关。您可以手动连接依赖项。DI帮助您完成SR(单一责任
void Say_Hello_World ()
{
  std::cout << "Hello World" << std::endl;
}
void Say_Something (const char *p_text)
{
  std::cout << p_text << std::endl;
}
Public Class MyClass
    Private ReadOnly mExLogHandlerService As IExceptionLogHandlerService

    Public Sub New(exLogHandlerService As IExceptionLogHandlerService)
        Me.mExLogHandlerService = exLogHandlerService
    End Sub

     ...
End Class