无论对象是否物理存在,我们都可以选择以不同方式对其进行建模。在许多情况下,我们可以随意使用归纳或组合。但是,GoF的“偏爱组合胜于一般化”原则指导我们使用组合。因此,例如,当我们对一条线进行建模时,我们将创建一个包含两个类型为Point(组成)的PointA和PointB成员的类,而不是扩展Point(广义化)。这只是我们可以随意选择合成或继承进行建模的简化示例,尽管对象通常要复杂得多。
我们怎么知道这是正确的选择?至少很重要,因为如果做错了,可能要进行大量的重构?
无论对象是否物理存在,我们都可以选择以不同方式对其进行建模。在许多情况下,我们可以随意使用归纳或组合。但是,GoF的“偏爱组合胜于一般化”原则指导我们使用组合。因此,例如,当我们对一条线进行建模时,我们将创建一个包含两个类型为Point(组成)的PointA和PointB成员的类,而不是扩展Point(广义化)。这只是我们可以随意选择合成或继承进行建模的简化示例,尽管对象通常要复杂得多。
我们怎么知道这是正确的选择?至少很重要,因为如果做错了,可能要进行大量的重构?
Answers:
这并不总是正确的选择。在大多数情况下,它是最有利的。当复合模型需要更改或扩展时,它具有更高的抵抗力,因为您可以更改组成而不必担心会无意影响其他类。
我们怎么知道呢?从经验,以及他人的经验。
我已经看到许多情况,从一个简单的概念开始就形成了庞大的类层次结构,这是您进行重大重构的地方。同时,我从未见过需要将组成结构重构为继承的情况。
但是我的轶事证据还不够。只要环顾互联网,就会有很多人有相同的经历。
我看不到组合和泛化是如何替代的,因此找不到引号。
组成和继承是(实现专门化),并且可以说抽象和泛化是(实现模块化)。
您想要的是设计简单合理,这是两种本质上很容易衡量的品质。
在您的情况下,似乎要用两点组成一条线而不是对其进行扩展,因为您自然会用两点定义一条线,而不是通过扩展点的概念来定义。
当两个候选人都符合条件时,就会受到青睐。该问题中所述的问题在此帐户上失败,因为它只有组合选项。
“合成也可以使用概括”。这句话对我们有意义吗?如果不是这样,那么我们还没有准备好掌握“赞成”规则。
我们之所以偏爱“组合”,是因为“组合”比泛化提供了更多的扩展性/灵活性。这种扩展/灵活性主要是指运行时/动态灵活性(这是通过接口和组合的组合来实现的)。
好处不是立即可见的。要查看好处,您需要等待下一个意外更改请求。因此,与那些接受组合的人相比,大多数情况下坚持概括的人都失败了(后面提到的一个明显的情况除外)。因此,规则。从学习的角度来看,如果您可以成功实现依赖项注入,那么您应该知道哪一个以及何时支持。当您不确定要选择哪个时,该规则可帮助您做出决定。同样,您应该能够首先看到两个选项都对其中一个有利。
摘要:组成:通过将一些较小的东西插入更大的物体中,可以减少耦合,而较大的对象只是将较小的对象回调。泛化:从第三方API的角度来看,定义一种方法可以被重写比定义一种可以调用的方法(要确保泛化是成功的),它的承诺更强。而且永远不要忘记,对于合成,您也正在从接口而不是大型类中使用泛化。但是不幸的是,全部功劳都归功于组成。