【问题标题】:Modeling question about categorization. To subtype or not to?关于分类的建模问题。分型还是不分型?
【发布时间】:2010-08-05 02:48:09
【问题描述】:

我需要一些关于如何为这个简单的分类 (?) 示例建模的建议:
我有一个产品。一个产品可以有不同的类型,例如 ProductType 1、ProductType 2 和 ProductType 3。所有产品都有一个部件号和一个名称。它们的不同之处在于价格的计算方式。

  • 类型 1 的产品价格取决于该产品的数量。所以如果我有 5 个产品,价格是 $x。如果我有 20 个产品,价格是 $y,以此类推。
  • 类型 2 的产品价格取决于每个产品的重量。如果重量为 5 公斤,则价格为 $x,以此类推。
  • 第 3 类产品的价格很简单,例如每件产品的价格为 $x。

在我看来,每个“价格结构”都需要有一个专用的表/类。然后,产品将参考其价格结构,具体取决于产品的类型。您是只创建一个“产品类型”表并在 Product 类上有一个名为 Type 的属性,还是使用泛化,因此 Product 1/2/3 是 Product 的子类型? 将有 5 种不同的价格结构,并且价格的计算方式因每种类型而异。因此,计算订单总价的逻辑取决于每种产品类型。

你能给我一些关于如何以最佳方式建模的建议吗?如果我选择在 Product 类上有一个 Type 属性的方法,我想我会在我的代码中得到很多 if-else 语句。如果我选择对它们进行子类化,每个类都可以负责计算正确的价格,或者它被要求做的任何事情。

【问题讨论】:

  • 对于特定类别的产品,价格是否也取决于实际零件编号,还是该类别的所有产品都相同?例如,所有第 3 类产品的价格都是 x 美元,还是您只是说它们是固定的并且与重量/数量无关?
  • 假设我销售 2000 件一件产品。如果产品是类型 1,价格将使用类型 1 的价格结构计算。如果它是类型 2,则必须使用另一个计算,依此类推。这能回答你的问题吗?
  • 我不同意子类化处理这种设计的最佳方式(见下面我的回答)。除此之外,这个 stackoverflow 讨论有很多关于将对象层次结构映射到关系数据库的良好反馈:stackoverflow.com/questions/3413459/…

标签: oop data-modeling subclassing categorization


【解决方案1】:

在我看来,这听起来像是何时使用 Strategy pattern 的完美示例。如果您使用类继承来定义产品的定价方式,那么如果后来有人决定 WidgetXYZ 现在应该按重量定价,而不是简单的价格,那么您将不得不重新编译整个系统。

我会将每个产品定义为具有“PricingStrategy” - 在您的情况下,这将是“volumeDiscount”、“byWeight”或“simple”。然后,您可以使用 Factory 根据产品的策略提供正确的 PriceCalculator 对象,该 priceCalculator 将相应地计算产品的价格。

【讨论】:

  • 我将不得不研究这种方法。谢谢你的建议!当我了解更多信息时,我可能会在几天后回到这里。
  • 我已经成功地实施了策略和工厂模式来解决我的问题,这似乎是一个很好的解决方案。谢谢!
【解决方案2】:

我的建议是,在您的关系数据模型中,您将有类型列来区分记录类型。在代码中,您绝对应该使用子类。域模型应尽可能独立于底层数据模型,并且您的描述很好地支持共享属性的需要(使用 ABC - Product 的抽象基类),P1、P2、P3 的子类型(给它一个有意义的域名) 和多态性来改变价格计算。

您的订单将包含基本产品参考列表,要获得总数,您将询问每个产品的价格并使用迭代器累积它们。

【讨论】:

  • 感谢您的评论。为什么不像这里描述的那样对子类化进行建模? tomjewett.com/dbdesign/dbdesign.php?page=subclass.php
  • db 中的建模子类不适合您的场景。当您的子类具有一组独特的属性时,您将像在您发送的示例链接中一样考虑这一点。在您的情况下,唯一的变化是类型和计算,它是派生的,而不是针对数据库中的字段存储/缓存的。如果您在数据库中对其进行建模,您最终将拥有包含 3 个其他产品表的产品表,并且它所拥有的只是一个具有 1:0 关系的 FK
  • 好点。非常感谢。我仍然愿意接受其他 cmets 和建议。
猜你喜欢
  • 2020-09-13
  • 2019-04-15
  • 2019-07-29
  • 2020-03-22
  • 2018-08-29
  • 1970-01-01
  • 2021-08-14
  • 1970-01-01
  • 2021-01-21
相关资源
最近更新 更多