1

所以说我有 A、B 和 C 类。A 类有一个单一的责任,但需要 B 类和 C 类的功能,所以起初我想让 A 从 B 和 C 继承,然后通过遵循“继承的组合”来实现原则和使 AI 的 B 和 C 成员可以降低设计的刚性,并使这两个类更具可重用性。

起初 B 和 C 只需要在 A 的构造函数中进行实例化,但最终它们的方法需要在其他两三个地方调用——因为我在其他地方重用了这些类,我忘记调用正确的地方会造成很多不必要的缺陷和浪费时间......我的问题是依赖注入是否有助于解决这个问题,它是否有助于降低使用组合的复杂性,如果是的话如何?

public class A
{
     private mB;
     private mC;
     public A(IB b, IC c)
     {
         mB = b;
         mC = c;
     }
     public MethodX()
     {
         mB.DoWhatever();
     }
     public MethodY()
     {
         mC.DoSomething();
     }
}

据我了解,DI 可以让我配置 IB 和 IC 的哪些具体类像这样通过构造函数并处理它的创建 - 但它还有什么帮助(复杂性方面)?

由于不理解这篇文章,我决定问这个问题:http: //lostechies.com/chadmyers/2010/02/13/composition-versus-inheritance/

对于现实生活中的示例,假设我有一个包含 EventListener 类的 State 类,该类必须在 State 调用其 Begin 方法时注册其事件,在调用其 End 方法时取消注册。

4

4 回答 4

3

依赖注入根本不帮助对象组合。在使用注入之前,您需要一定程度的可组合性。通常,依赖反转用于反转传统的依赖,以便依赖可以通过抽象来建模,这些抽象本身可以被注入到其他东西中,而无需直接耦合。注入是一种反演形式,有助于解耦,而不是合成。

于 2012-08-14T03:19:34.273 回答
1

你的推理是合理的,你在正确的轨道上。

通过接口/抽象使用 DI 和组合使得 bot 更容易测试和构建代码。您可以在构建 A 时使用 B 和 C 的临时“假”实现,如果这有助于您的过程。

典型的解决方案是将 A、B 和 C 的构造和配置分解为工厂类或 A 的子类。

于 2012-08-14T08:52:15.197 回答
0

我认为您对 DI 的理解是正确的。通过从类 A 中删除类 B 和 C 的实例化,DI 减少了它们之间的耦合。现在类 A 依赖于抽象接口 IB 和 IC,而不是它们的具体实现。这使得 A 类的代码更加灵活(如果需要,您可以通过简单地重新配置 DI 容器轻松地注入 IB 和 IC 的其他一些实现),并且可测试(您可以注入 IB 和 IC 的模拟实现)。此外,可以说它使 A 类的代码更具可读性,因为现在它对协作者 IB 和 IC 的依赖已通过构造函数的签名明确体现。

于 2012-08-14T03:17:02.827 回答
0

在处理依赖关系时,依赖注入通过自动化和管理这些依赖关系的创建,在一定程度上抵消了复杂性。(当使用 Autofac 或 Unity 等 IOC 容器实现时)在 A、B 和 C 的简单示例中,可能很难看到任何真正的节省。您开始看到复杂性降低的地方是当您实现依赖于 C 的 D 类时。促进您的 DI 的 IOC 容器将知道如何组合 A、B 和 C(使用 A 和 B),因此您的手卷代码不需要担心创建对象实例以作为依赖项传递。通过复杂性,我指的是管理依赖项所需的代码/保姆数量。

正如 Peter 所指出的那样,IOC 和 DI 真正闪耀的地方在于将依赖关系相互分离,以便可以单独测试代码。如果您想为 C 类编写单元测试,但 C 创建了 A 和 B 的实例,则不能与 A 和 B 隔离测试。当 A 或 B 类似于数据服务或文件服务时,这可以进行单元测试痛苦。利用 IOC,C 接受对那些可以模拟的服务的合约接口的引用。通过这种方式,C 可以通过其依赖项的可预测行为进行测试。

于 2012-08-14T05:46:58.743 回答