【问题标题】:Alternatives to a deep inheritance hierarchy?深度继承层次结构的替代方案?
【发布时间】:2012-10-11 19:19:25
【问题描述】:

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

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

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

Product > Component > GraphicsCard > NvidiaGraphicsCard

这样做的原因是因为我希望对每个Product 的属性进行细粒度控制。这允许我包含特定于 NvidiaGraphicsCard 的属性,这些属性不适用于 ATiGraphicsCard

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

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

【问题讨论】:

    标签: oop inheritance orm language-agnostic domain-driven-design


    【解决方案1】:

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

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

    相反,我会选择一个Product 类,它可以由特定于产品的描述符或属性字典组成。这将 OrderItem 在不知道具体产品类型的情况下引用 Product - 不需要多态性。这也将更容易允许新类型的产品 - 无需创建新的子类。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          猜你喜欢
          • 2012-06-18
          • 1970-01-01
          • 2014-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多