【问题标题】:Is is an anti-pattern to inject DI container to (almost) each class?将 DI 容器注入(几乎)每个类是一种反模式吗?
【发布时间】:2012-04-28 04:19:36
【问题描述】:

最近我发现自己不太关心为类定义依赖项并将它们传递给构造函数,但我总是传递 DI 容器并将其保存在私有属性中。这样我的类就不会有非常明确的依赖关系,当我需要时,我会从容器中获取所有内容。

虽然我对这个解决方案有一些不好的感觉(除了访问容器造成的开销),但我真的想不出太多的缺点。也许对依赖项的松散定义会降低类的可移植性,或者我在重构时会感到意外......?

您对此有何看法?

【问题讨论】:

标签: dependency-injection


【解决方案1】:

完全错误。不要将 DI 容器放入对象中;他们不需要知道或关心他们正在被注射。这不符合“不要给我们打电话;我们会打电话给你”。

反之亦然:整个应用程序都知道 DI 引擎,但随后它会从中获取所需的 bean。

我想你可能会争辩说注解改变了一些关系,因为现在 bean确实知道它们是连接在一起的事实。但是当配置被外部化为 XML 时,bean 确实不知道 DI。

【讨论】:

    【解决方案2】:

    这是一种反模式,我敢打赌你还没有为你的代码编写测试,这真的很糟糕。

    当你开始编写测试时,你会发现你正在编写不可测试的代码,而你是:

    • 使用服务定位器反模式

    • 你违反了得墨忒耳法则

    • 您没有遵循单一职责原则

    • 你隐藏了你的对象真正的依赖(不使用依赖注入模式)

    • 在任何应用程序中,您都没有真正分离两大堆对象:

      • 业务对象:职责是业务逻辑、领域抽象
      • 连接和构建对象:职责是构建对象图

    在您想为组件编写单元测试的那一天,您会后悔这个决定,您将要么重构代码,要么编写集成测试而不是简单的单元测试(创建一个测试容器并将模拟注入此容器) .

    我的建议是阅读本指南以编写可测试的代码:(这是在 Google 努力工作的人使用的指南)

    http://misko.hevery.com/code-reviewers-guide/

    如果您愿意,可以从 Misko Hevery 的这些关于测试心理学和干净代码讨论的视频开始:

    http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded

    http://www.youtube.com/watch?v=RlfLCWKxHJ0&feature=player_embedded

    http://www.youtube.com/watch?v=-FRm3VPhseI&feature=player_embedded

    【讨论】:

    • 我认为你在这里有点夸张了这种情况。我确实在为我的类编写单元测试,但我没有看到如何在我的 DI 容器中定义固定装置而不是直接传递它们会使事情变得复杂。我也不同意您关于 SRP 的观点,并且仅部分同意您对 demeter 定律(它是一个容器)的看法。你在这里暗示的东西太多了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 2021-06-29
    相关资源
    最近更新 更多