【问题标题】:dependency inversion in programs with many classes (C++)具有许多类的程序中的依赖倒置 (C++)
【发布时间】:2018-05-03 18:23:07
【问题描述】:

我正在尝试将一些旧的 C++ 代码转换为更可测试的形式。为了符合依赖倒置原则(DIP),我会在很多情况下使用依赖注入。

我的问题是如何最好地实例化具体类。这段代码中有 100 个我自己的类。在他的《清洁架构》一书中,罗伯特·马丁认为这些类是易变的,应该在工厂中实例化。但是(参见本书的第 90 页),我要实例化的每个类需要 4 个类。这意味着 400 个课程。

为了便于说明,假设旧代码有一个类 A(它实例化并使用类 A1 到 A5)、B(B1 到 B10)和 C(类 C1 到 C3)。

在新代码中,您建议如何以及在何处实例化所有具体类?我特别想听听任何在大型 C++ 程序中处理过此类问题的人的意见。谢谢。

布鲁斯

【问题讨论】:

  • 如果有人有你引用的那本书,你的问题是可以理解的。所以得到答案的概率是 P("one has the book")*P("one has the same problem")*P("He will be on the site in the next hour") = 当然是一个小数字。你可能不会有任何答案。

标签: c++ dependency-injection dependency-inversion


【解决方案1】:

在应用依赖倒置原则时,我们将协作组件图(也称为对象图)的构建延迟到最后负责的时刻。由于我们希望最小化组件之间甚至单个库之间的耦合,因此我们将这些对象图的构建移至系统中最不稳定的部分。这是启动程序集。启动程序集中负责组合和构建这些对象图的部分通常称为Composition Root

在新代码中,您建议如何以及在何处实例化所有具体类?

您应该在 Composition Root 中构建所有具体的组件(包含应用程序有趣行为的类)。

在一些托管环境中,如 Java 和 .NET,API 的可用性使我们能够在运行时查询应用程序的元数据(也称为反射),允许在编译时声明抽象和实现之间的关系,并允许组件在运行时使用通常称为 DI Containers 的可重用库动态构建。

C++ 可能没有这种在运行时查询元数据的能力。在这样的环境中,你使用Pure DI,这意味着:你在Composition Root中手动new你的类。

请注意,在我的描述中,我没有使用“工厂”这个词。需要指定返回其他应用程序抽象的工厂抽象不应该是常态,而是the exception。您可能会将您的合成根视为一个大工厂,但应用程序中的任何内容都依赖于合成根。另一方面,Composition Root 取决于一切。

因此您的应用程序类几乎不需要依赖工厂抽象。如果一个类需要不同的服务,它应该直接将它注入到它的构造函数中,而不是注入一个可以解析该服务的工厂。

【讨论】:

  • 一个问题。也许我遗漏了一些东西,但在许多情况下,要实例化的对象是否不需要仅在运行时可用的参数以及依赖项?示例:具有多个不同构造函数的对象,每个构造函数都有不同的参数。您将如何处理这种情况?
  • “不要被实例化的对象需要仅在运行时可用的参数以及依赖项”。 Nope.
猜你喜欢
  • 2016-01-02
  • 2021-12-28
  • 1970-01-01
  • 2019-03-23
  • 2022-11-20
  • 2019-10-31
  • 1970-01-01
  • 2021-12-04
  • 2015-03-14
相关资源
最近更新 更多