Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 深层继承层次结构的替代方案?_Oop_Inheritance_Orm_Language Agnostic_Domain Driven Design - Fatal编程技术网

Oop 深层继承层次结构的替代方案?

Oop 深层继承层次结构的替代方案?,oop,inheritance,orm,language-agnostic,domain-driven-design,Oop,Inheritance,Orm,Language Agnostic,Domain Driven Design,我试图用一组综合属性对产品进行建模。通常,在线商店会使用文本描述来列出特定产品的属性。然而,这个解决方案不是最优的 例如,以下链接显示同一产品的文本描述中的属性不一致,但制造商不同: 因此,我选择了如下继承层次结构: 产品组件图形卡nvidiagraphcard 这是因为我希望对每个产品的属性进行细粒度控制。这允许我包括特定于nvidiagraphiccard的属性,这些属性不适用于ATiGraphicsCard 注意,除了向子类添加更多字段外,继承还允许我利用多态性,使OrderIt

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

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

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

产品
组件
图形卡
nvidiagraphcard

这是因为我希望对每个
产品的属性进行细粒度控制。这允许我包括特定于
nvidiagraphiccard
的属性,这些属性不适用于
ATiGraphicsCard

注意,除了向子类添加更多字段外,继承还允许我利用多态性,使
OrderItem
保存对
产品的引用。这就是我排除作文的原因


拥有这么深的继承层次结构有问题吗?如果有,有什么解决方案或模式来处理这个问题吗?

这是一个关于继承的教科书示例,一个很好的示例。我认为这种模型没有什么错,只是在关系数据库中持久化它会很困难

另一方面,有时一组属性只与无法通过单一继承表达的项的子集相关。例如,
功耗
描述给定产品所需的电量与鼠标和U盘无关。另外,重量对于某些组件来说并不重要。这意味着您可以研究具有特性的语言,如Scala,以使您的模型尽可能干燥


请注意,深度继承不会对性能造成任何损失-更长的继承链并不意味着更慢的虚拟方法调用(因为这些只是数据容器,所以您不会经常使用虚拟调用)。

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

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

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

相反,我希望有一个
产品
类,它可以由特定于产品的描述符或属性字典组成。这将使
OrderItem
引用
产品
,而不知道具体的产品类型-不需要多态性。这也使得允许新类型的产品变得更容易——无需创建新的子类