所以说我有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方法时取消注册。
答案 0 :(得分:3)
依赖注入根本不会有助于对象组合。在甚至可以使用注射之前,您需要一定程度的可组合性。通常,依赖性反转用于反转传统的依赖性,以便依赖性可以通过抽象来建模,抽象本身可以在没有直接耦合的情况下注入其他东西。注射是一种反转形式,有助于解耦,而不是组合。
答案 1 :(得分:1)
你的推理是合理的,你走在正确的轨道上。
通过接口/抽象使用DI和组合使得机器人更易于构建和构建代码。在构建A时,您可以使用B和C的临时“假”实现,如果这有助于您的过程。
典型的解决方案是将A,B和C的构造和配置分解为工厂类或A的子类。
答案 2 :(得分:0)
我认为您对DI的理解是正确的。 通过从A类中删除B类和C类的实例化,DI使它们彼此之间的耦合较少。现在,A类依赖于抽象接口IB和IC,而不是它们的具体实现。这使得A类代码更加灵活(如果需要,您可以通过简单地重新配置DI容器轻松注入其他IB和IC实现),并且可测试(您可以注入IB和IC的模拟实现)。 此外,它可以说使类A的代码更具可读性,因为现在它对协作者IB和IC的依赖性明确体现在构造函数的签名上。
答案 3 :(得分:0)
依赖注入通过自动化和管理这些依赖项的创建来处理依赖项,从而抵消了复杂性。 (当使用诸如Autofac或Unity之类的IOC容器实现时)在A,B和C的简单示例中,可能很难看到任何真正的节省。你开始看到降低复杂性的地方是当你实现D类依赖于C时。一个IOC容器促进你的DI将知道如何组成A,B和C(使用A& B)所以你的手 - roll代码不需要担心创建要作为依赖项传递的对象的实例。根据复杂性,我指的是管理依赖关系所需的代码/保姆数量。
正如彼得所指出的那样,IOC和DI真正发挥作用,将相互依赖性分离,以便可以单独测试代码。如果你想为C类编写单元测试,但是C创建了A&的实例。 B,不能单独测试A& A; B.当A或B类似于数据服务或文件服务时,这会使单元测试变得痛苦。利用IOC,C接受对可以模拟的服务的契约接口的引用。这样,C可以通过其依赖性的可预测行为进行测试。