【问题标题】:inheritance vs. composition for testability可测试性的继承与组合
【发布时间】:2010-10-20 02:47:00
【问题描述】:

在设计我的对象时,从可测试性的角度来看,我发现组合是更好的选择。原因是,如果需要,我可以在运行单元测试时模拟部分组合结构。如果我有继承层次结构,这是不可能的。

我想知道其他人是否也发现这是更喜欢作曲的原因。另外,由于使用了继承,您还遇到了哪些其他可测试性陷阱?

【问题讨论】:

    标签: inheritance composition testability


    【解决方案1】:

    这取决于上下文。当类很简单并且从简单的公共类(配置/记录器)继承时,继承获胜。我是其他情况下的作文大多是赢

    【讨论】:

      【解决方案2】:

      我相信,您越是开始使用设计模式进行开发,您就会越来越多地发现组合比继承更受青睐。实际上,我相信 Head First: Design Patterns 一书认为“Favor Composition Over Inheritance”是主要的设计原则之一。

      您能够模拟部分组合进行测试的示例可能是最好的示例之一。

      编辑:虽然设计模式的基本原则是支持组合而不是继承,但这并不意味着没有在需要的地方使用继承的设计模式。另一个基本示例是装饰器模式,您在其中编写抽象超类(尽管这是用于类型匹配而不是实现“is-a”关系)。

      【讨论】:

      • 嗯...希望我知道为什么有人投了反对票。如果我知道一个特定的原因,我可以尝试澄清或修改。
      • 实际上,“能够模拟部分组合进行测试”根本不是一个好例子。组合变得更容易的真正原因在于大多数模拟工具的技术限制。消除这些限制,模拟继承变得和模拟组合一样容易。除此之外,我完全同意优先组合而不是继承是一个好主意。
      • 模拟部分组合是否也需要依赖注入(使其成为聚合)?我将如何在单元测试中访问该组件?
      【解决方案3】:

      我认为组合更容易测试的最大原因是(实现)继承往往会创建耦合度很高的类,这些类更脆弱(脆弱基类)并且更难单独测试。

      继承肯定有它的用途,但我发现自己越来越喜欢组合而不是继承。

      【讨论】:

      • 我发现它是解释继承与组合在测试方面差异的唯一答案。值得投票。
      【解决方案4】:

      “优先对象组合优于类继承”实际上来自 GoF 书籍。这个conversation 和 Erich Gamma 描述了书中的这个想法。

      需要继承的一个重要模式是模板方法模式。这种模式被广泛使用,非常方便,所以继承就在这里。另一个使用继承的常见模式是复合模式。我试图说明的一点是,根本不贬低继承,但我希望通过查看这么多常见的 API 就能清楚地知道......

      【讨论】:

        【解决方案5】:

        这不是非此即彼的情况。他们不是竞争对手。

        继承也很容易进行单元测试。但是,它有时需要模拟具体类来测试抽象超类。

        继承很容易被不当使用。有些设计看起来像“是”的情况,但实际上并非如此——它们更加微妙。有时它真的是“类似行为”,您需要某种组合(例如,策略)将行为与其他属性分开。

        【讨论】:

        • 听起来很像 Head First: Design Patterns 中的第 1 章,即“策略模式”,在该“策略模式”中,您被教导设计和编码到接口而不是实现。
        • 伟大的一点是它不是非此即彼的。最近,我发现自己对作曲进行了如此多的宣传,仅仅是因为“is-a”经常被误认为“behaves-like”——至少在我的经验中是这样。很高兴提醒他们每个人都有自己的位置。
        【解决方案6】:

        The Gang of Four Design Patterns 这本书基本上都是关于为什么更喜欢组合而不是继承,并提供了许多方法来做到这一点。一些原因:

        1. 类增加了代码库的复杂性

        2. 在许多较新的语言中,继承仅限于一个类,而您可以随心所欲地进行组合
        3. 无法在运行时更改基类(本质上是您遇到的问题)。

        【讨论】:

        • 班数和这个有什么关系?组合是否意味着比继承时更少的类?
        • 也许吧。装饰器模式结合使用继承和组合,与仅使用继承相比,生成的类更少。
        猜你喜欢
        • 2011-05-20
        • 1970-01-01
        • 1970-01-01
        • 2017-08-19
        • 2014-01-17
        • 2015-03-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多