【问题标题】:Constructor Injection: How many dependencies is too many? [closed]构造函数注入:有多少依赖项太多了? [关闭]
【发布时间】:2009-06-04 22:15:44
【问题描述】:

我现在一直在使用手动构造函数注入 DI。我注意到的一件事是我的构造函数开始变得相当长。

我有一个依赖于一堆小对象的类 - 有时介于 6 到 10 个之间。随着我继续将我的应用程序分成更小的块,我可以看到这个数字随着时间的推移而增加。这是一个常见的问题吗?

显然,这在很大程度上取决于项目。但是,基本问题是这样的:

你什么时候开始对一个类的依赖数量感到不安?您使用哪些策略来减少这些依赖关系?

【问题讨论】:

    标签: dependency-injection


    【解决方案1】:

    这可能表明具有 6-10 个依赖项的类本身需要重构。

    【讨论】:

    • 如果你找不到逻辑方法将它们分组为多个类,如 WW。提及?您是否同意拥有许多依赖项是可以的?我的意思是,可以说依赖是汽车品牌:宝马、欧宝、大众等。它们都是汽车。也许不是最好的例子,但我希望你能明白。
    • @Darius.V - 如果您有一个具有 50 个品牌依赖项的 Cars 类,那么显然您违反了 SRP。您需要将它们分组为共同特征(即ElectricCarsHybridCarsDieselCarsGasolineCars),因此您的顶级 Cars 类只有几个依赖项,每个依赖项都有共同的属性和方法。在此之下,您可以使用 strategy pattern 将多个类似的汽车简化为一个依赖项(例如,只需将一个 GasolineCarsStrategy 注入到管理所有汽油汽车的汽车类中)。
    【解决方案2】:

    我不会担心的。

    相反,我会担心这个类太复杂。

    一个具有许多依赖项的类,它全部使用它们但没有循环或 if 语句很好。在我最近编写的一些代码中,一个类中有大约 14 个依赖项。但是,代码中只有一条路径,没有逻辑方法可以将依赖项分组到更好的类中。

    依赖项少的类,包含很多分支语句或复杂的循环条件,应该简化。

    【讨论】:

      【解决方案3】:

      我认为不会超过三四个。如果你得到的不止这些,我会开始考虑你对concerns 的抽象程度如何。例如,单个 repository 对象应该可以满足您在相关类中的所有数据检索需求。

      【讨论】:

      • 大概,如果一个对象需要访问数据库和某种方式与外部通信(例如,存储库和 IO),那么这已经是分配的 4 个依赖项中的 2 个依赖项。此外 - 不是其中之一- 确保每个类都有单一职责(单一关注点)会导致更多类而不是更少类的影响?最终,需要有一个可以编排所有这些较小部分的类......并且该类将具有许多依赖项才能发挥作用。
      • @Runcible,非常正确。如果您描述的合并发生,您确实将更少的东西注入到构造函数中。你所描述的顺便说一句是一个控制反转容器(例如温莎)。
      • @Runcible,我最近一直在努力解决这个依赖注入的问题。我发现了两个很有帮助的帖子。 blog.ploeh.dk/2010/01/20/… & blog.ploeh.dk/2010/02/02/RefactoringtoAggregateServices 另外一点,我相信 SRP 的目的不是让一个类只做一件事,而是有一个从业务角度改变的理由。
      【解决方案4】:

      可运行,

      这是温莎城堡项目的链接。它是一个Inversion of Control 容器。这些容器允许工厂类将您的依赖项收集在一起并将它们作为单个对象注入到您的构造函数中。

      http://www.castleproject.org/container/index.html

      我听说过温莎的好消息。 Spring 也创建了一个 IoC 容器,there are others

      【讨论】:

        【解决方案5】:

        具有 6-10 个依赖项的类是代码异味。这表明该类可能违反了Single Responsibility Principle

        您使用哪些策略来减少这些依赖关系?

        Mark Seemann 在他的帖子Refactoring to Aggregate Services 和他的书Dependency Injection in .NET 中明确了这一任务。您的类具有如此多的依赖项这一事实表明该类中有多个职责。通常有一个隐式域概念等待显式通过识别它并使其成为自己的服务。一般来说,大多数类不应该需要超过 4-5 个依赖项。

        【讨论】:

        • 关于 SRP:假设您有一个 API 控制器,其中包含 10 个 HttpGet 方法和 10 个依赖项——一个用于处理每个方法的逻辑。每个方法都与控制器相关,但它们都从不同的来源请求数据,因此需要自己处理。所有 10 个依赖项都使用相同的通用接口,但具有不同的模型。控制器中不执行任何逻辑。在这种情况下,我仍然会考虑这个控制器 SOLID,不管有很多依赖项。
        【解决方案6】:

        您可能还想查看构造函数的任何参数是否也应该合并到一个类中(假设这些参数作为一个类有意义)。

        您可能还想考虑将 ServiceLocator 模式用于您的某些依赖项。如果您必须将依赖项传递到一长串构造函数中,则尤其如此。

        【讨论】:

        • 服务定位器模式有点与依赖注入原则相反。服务定位器违反得墨忒耳法则:youtube.com/watch?v=RlfLCWKxHJ0
        • 非常好的视频,Runcible。对 DI、IOC、Service Locator 的解释非常通俗易懂。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-24
        • 2011-06-11
        • 2016-01-01
        • 2011-02-02
        • 1970-01-01
        • 1970-01-01
        • 2019-04-20
        相关资源
        最近更新 更多