6

我正在尝试对具有一组综合属性的产品进行建模。通常,在线商店会使用文本描述来列出特定产品的属性。然而,这个解决方案不是最优的。

例如,以下链接显示同一产品的文本描述中的属性不一致,但制造商不同:

因此,我选择了如下继承层次结构:

Product> Component> GraphicsCard>NvidiaGraphicsCard

这样做的原因是因为我希望对每个Product. 这允许我包含特定于 a 的属性NvidiaGraphicsCard,但不适用于 a ATiGraphicsCard

OrderItem请注意,除了向子类添加更多字段外,继承还允许我在持有对 a 的引用方面利用多态性Product。这就是我排除作曲的原因。

拥有如此深的继承层次是否有问题,如果有,是否有任何解决方案或模式来处理这个问题?

4

3 回答 3

8

由于几个原因,在 DDD 和 ORM 的上下文中,深层继承层次结构存在问题。当您尝试定义实体的身份时,就会出现一个问题。AProduct必须基于身份与其他产品进行比较,无论要比较哪个子类。可以在Product类中提供此功能,但必须注意确保子类也可以进行比较,并且存在一些问题。例如,NHibernate 将为类生成一个代理,因此对象的实际运行时类型将不是NvidiaGraphicsCard从它继承的代理。虽然临时实例NvidiaGraphicsCard不会成为代理。这意味着您无法根据类型比较它们。

另一个困难是配置 ORM 映射以支持继承。虽然大多数 ORM 都允许这样做,但生成的映射和生成的 SQL 通常很复杂。您是否将所有子类存储在一个表中?在具有通用产品表外键的多个表中?在前者中,您最终会得到一张巨大的桌子。在后一种情况下,您的查询将受到影响,因为所有子类表都需要连接。关系模型和对象模型之间存在太多的阻抗不匹配。事件如果使用文档数据库,最好支持组合而不是继承。

Instead, I would go for having a single Product class, which can be composed of either product specific descriptors, or a dictionary of attributes. This would an OrderItem to reference a Product without knowing the specific product type - no need for polymorphism. This would also make it easier to allow for new types of products - no need to create a new sub-class.

于 2012-10-13T21:07:47.970 回答
1

这是一个关于继承的教科书示例,一个很好的例子。我认为这种模型没有任何问题,只是在关系数据库中保存它会很困难。

另一方面,有时一组属性仅与无法通过单一继承表示的项目子集相关。例如PowerConsumption,描述给定产品需要多少功率与鼠标和 USB 记忆棒无关。对于某些组件,重量也不是很重要。这意味着您可能会研究具有特征的语言,例如 Scala,以使您的模型尽可能 DRY。

请注意,深度继承没有性能损失——更长的继承链并不意味着更慢的虚拟方法调用(好吧,你不会经常使用虚拟调用,因为它们只是数据容器)。

于 2012-10-11T19:25:07.283 回答
0

我建议您查看装饰器模式。这样,您将拥有所需的任何技巧和不到十亿的课程。

于 2012-10-11T19:34:25.167 回答