【问题标题】:Dependency Injection: Difference between loose coupling mechanisms based on interface and class?依赖注入:基于接口和类的松耦合机制的区别?
【发布时间】:2015-08-30 20:59:39
【问题描述】:

假设,我有 2 个配置。

第一个:

interface I {
    ...
}

class A implements I {
    ...
}

class B implements I {
    ...
}

class Component {
    I i;    
    Component (I i) {
        this.i = i;
    }
}

第二个:

class C {
    ...
}

class A extends C {
    ...
}

class B extends C {
    ...
}

class Component {
    C c;    
    Component (C c) {
        this.c = c;
    }
}

这两种配置使用两种不同的松耦合机制(基于接口和基于类)有什么区别?

为什么我需要使用接口而不是类?

【问题讨论】:

标签: java dependency-injection loose-coupling


【解决方案1】:

主要是,使用类是一种更繁重的方法。基类通常包含具体(非抽象)方法。如果你从它们派生,你还需要继承这些你可能不想要的具体方法。

例如,假设您想从 decorator pattern 这样的组合设计模式中受益。在这里,您的装饰器还需要从基类派生并继承具体方法。但是,您的装饰器不需要具体的方法来运行。

总而言之,如果您的抽象是基于类的,那么进行对象组合会更加困难/不干净。

另一方面,通过接口进行抽象并不强制实现类继承任何具体的方法实现。因此,它更干净。

【讨论】:

    【解决方案2】:

    一个对象可以实现多个接口但只能扩展一个类,因此有时松耦合库的用户可能无法扩展您的类。

    当你扩展时,你将超类的代码合并到你的代码中,有时没有代码可以合并,所以实现更适合。

    最后它不是同一个范式,当你写“B extends A”时,你会说“我是 A,我做同样的事情,但我也可以做其他事情”。当您写“B 实现 A”时,您会说“我是 B,但您可以将我视为 A”。

    长话短说,唯一的实际原因是第一个。

    【讨论】:

      【解决方案3】:

      基于接口的层次结构是一种很好的设计方法,因为它简化了实现:您总是可以实现一个接口,但并不总是可以扩展一个类(例如,最终类)。或者,另一方面,类的作者并不总是希望它被扩展。

      所以,您对在类上使用接口非常感兴趣,因为通过这种方式,您可以接受更广泛的实现。例如:

      使用类:

      class Component
      {
          AbstractList c;
          Component (AbstractList c){...}
      }
      

      ...Component 将接受 ArrayList 或 Vector。

      相反,使用接口:

      class Component
      {
          List c;
          Component (List c){...}
      }
      

      ...Component 将能够接受 ArrayList、Vector、CopyOnWriteArrayList...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-26
        • 1970-01-01
        • 2017-06-05
        • 1970-01-01
        • 1970-01-01
        • 2020-05-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多