32

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

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

4

6 回答 6

33

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

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

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

于 2009-04-17T13:46:13.627 回答
10

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

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

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

于 2009-04-17T13:50:08.220 回答
8

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

  1. 类的数量增加了代码库的复杂性。
  2. 在许多较新的语言中,继承仅限于一个类,而您可以随心所欲地组合。
  3. 基类不能在运行时更改(本质上是您遇到的问题)。
于 2009-04-17T13:49:30.420 回答
6

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

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

于 2009-04-17T13:59:28.650 回答
3

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

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

于 2009-04-17T13:57:57.967 回答
0

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

于 2021-04-03T12:54:28.073 回答