你会如何设计你的申请?通过继承还是通过组合?

时间:2011-06-24 11:23:51

标签: design-patterns architecture

这是一个设计问题/讨论。

我创建了一个包含大约50个类的解决方案。

我通过引入包含类之间共享信息的新抽象类来重构类并删除重复的代码,以便这些类继承它们。

E.g。

Abstract ColumnBuilder
ColumnBuilderForDepartmentReport : ColumnBuilder
ColumnBuilderForStoreReport : ColumnBuilder

现在我的设计中包含很多类,并且删除了重复的代码,这是一件好事。

这是一个好的设计吗?

我听说我们应该更喜欢使用Composition而不是继承。

它如何适用于您希望使用继承来删除重复代码的这种情况?我应该重构代码以使用Composition吗?怎么样?

由于

3 个答案:

答案 0 :(得分:2)

根据情况需要,你需要两者。组合是创建类的首选,但是当你需要'is-a'关系时,继承是有意义的。

在您的情况下,这意味着继承了唯一的ColumnBuilder类型,然后可以通过组合在其他类中使用(对于“has-a”关系)。

例如,一个具有ColumnBuilder的Report类,它允许您分配任何一个唯一的类(以及任何将来的ColumnBuilder继承者),这要归功于可继承类类型的组合。

答案 1 :(得分:1)

您错过了使用Interfaces with Composition - 这为您提供了Composition的灵活性,但保留了继承的多态性。

E.g。你可以定义一个接口:IColumnBuilder,并且所有3个类都实现了这个接口。

关于您的代码是否设计良好 - 无法从提供的信息中分辨出来。很多课程都不是坏事 - 一段字符串有多长?

  

我的经验法则:

     

1)当您的子类“is-a”超类时使用继承 - 在示例中,您引用它们是所有列构建器,因此继承将是我的选择。这使得添加新的列构建器类型变得更加容易。

     

2)使用组合,你想要实现的只是代码重用。

     

3)如果你试图获得多态性,但规则1不适用(没有“是-a”关系),那么使用带接口的组合。

答案 2 :(得分:1)

  

我听说我们应该更喜欢使用Composition而不是继承。

一般都是好建议。但这并不意味着你应该全部替换它们。

如果您的子类需要超类中的所有内容,并且每个子类都添加了一小部分函数,​​那么您可以继续使用继承。

  

它如何适用于您希望使用继承来删除重复代码的这种情况?我应该重构代码以使用Composition吗?怎么样?

您还可以使用合成来删除重复的代码。

您正在寻找的重构是Replace Inheritance with Delegation。谷歌搜索这个短语可能会发现一些参考文献比示例图更详细,但你真的应该得到这本书Refactoring