【问题标题】:Entity Inheritance in DDDDDD 中的实体继承
【发布时间】:2017-12-28 19:16:25
【问题描述】:

我正在尝试使用 DDD 指南设计电子商务系统的域模型。我有一种情况,我有 2 种不同类型的产品。一种产品是“项目”,另一种产品是“包裹”(项目组/捆绑)。到目前为止,我的域模型看起来像这样

public abstract class Product : IAggregateRoot
{
    public string ProductId { get; protected set; }

    // Many to Many relationship between Item and Package
    protected List<ItemPackageRelationship> ItemPackages => new List<ItemPackageRelationship>();

    protected List<Image> Images => new List<Image>();

    // Other properties shared between Item and Package
}

public class Item : Product
{
    // All properties and methods specific to Item

    public void SetImages(List<string> images)
    {
       // Set images for Item has its own business logic

       // Example: number of allowed images, size of image etc
    }
}

public class Package : Product
{
   // All properties and method related to package

    public void SetImages(List<string> images)
    {
       // Set images for Package has its own business logic

       // Exampe: number of allowed images, size of image etc
    }
}

所有行为都在 Item 和 Package 类中定义,而 Product 类只是具有共享属性。最初我想创建 2 个完全独立的聚合根(项目和包)并且没有产品实体。我需要 Product 的唯一原因是系统中的 Unique ProductId。并且与其他实体(如图像)的所有关系都需要基于 ProductId。

我不是 100% 确信我正在设计的内容是正确的,并且需要在这里输入一些信息。创建一个 Base 实体只是为了共享一些属性是违反 DDD 的任何原则的吗?你们还有什么建议可以改进我的领域模型的设计吗?

非常感谢。

【问题讨论】:

  • EF 类模型不是域模型。它是数据访问层的一部分,它应该被设计为尽可能顺利地执行该任务。意识到这一点应该可以帮助您设置正确的优先级。对于其余部分,这是相当基于意见的。

标签: c# entity-framework domain-driven-design


【解决方案1】:

我认为实体的继承应该由行为驱动,而不是由属性驱动。 换句话说,您应该查看其他业务代码,而不是实体本身。如果您看到相对较多的地方应该使用ItemPackage 以相同的方式使用iheritence(但并非绝对必要)。如果唯一的原因是共享唯一标识符,那么继承是不合理的。

【讨论】:

  • 您好,感谢您的回复。所以事实是项目和包装(项目捆绑)都是我们销售的产品。两者在属性和行为方面都有些相似。我知道在设计我的领域模型时我不应该考虑数据库结构,但我不能忽视他们都需要进入同一个产品表的事实。那么在这种情况下,是否可以从抽象类(即产品)派生项目和包(2 个聚合根)?
  • 是否使用同一张表是一个实现细节,它不应该影响域的设计!想想逻辑和行为。如果有很多逻辑是项目和包的通用逻辑,您可以使用继承(但如果逻辑位于实体之外,您也可以使用接口)。另一种方法:您可以不使用继承开始,如果在某个时间点您注意到您为 Package 和 Item 编写了大量重复代码,您可以重构为继承。
  • 界面对我来说是个好主意。现在就像我提到的,因为物品和包裹都是产品,它们有一些共同的属性......让我们说重量,价格等......对于物品重量是根据物品重量计算的,但对于包裹,它是所有重量的总和在那个包中(这只是一个例子,在 Item 和 Package 之间有 6-8 个共享属性,具有不同的实现)。我还尝试使用 Product 实体和 ProductType(Item 或 Package)来设计我的模型。但我最终进行了很多 IF 检查(基于我返回值的类型)。
  • 现在,如果我使用接口,创建 2 个聚合(项目和包),我将拥有一些共享值对象(ProductImage、ProductLocation 等)。您认为聚合之间可以共享值对象在这种情况下?
  • 我无法给出明智的答案,因为我不了解您的领域、对价值对象的要求以及围绕它的逻辑。但是共享价值对象本身并不是一个坏主意。我不能说任何反对它。
猜你喜欢
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 2011-05-19
  • 2010-10-07
相关资源
最近更新 更多