【问题标题】:Shall I model article category as value object when design with DDD?使用 DDD 进行设计时,我应该将文章类别建模为值对象吗?
【发布时间】:2021-01-01 23:50:53
【问题描述】:

我最近正在学习 DDD,并在建模文章类别中苦苦挣扎。文章管理系统的逻辑如下。

我们有一个可以管理文章的系统。每篇文章可以属于多个分类,一个分类可以有多篇文章。

class Category: IValueObject
{
  public string Name { get; set; }
  public string Description { get; set; }
}

class Article: IAggregateRoot
{
  public int Id { get; set; }
  public string Title { get; set; }
  public string Content { get; set; }
  public IEnumerable<Category> Categories { get; set; }
}

阅读文章和书籍后,我很困惑Category应该建模什么类型的域模型。似乎将其建模为值对象或聚合根是合理的。

对于值对象,我觉得 Category 是由 Name 属性标识的。如果两个类别具有相同的名称,则可以肯定地说它们是同一类别。此外,类别是文章的属性,因此留在文章的域中可能会很好。

对于聚合根,我正在考虑为 CRUD 类别提供一个独立的网页,包括将一篇文章分配给类别管理页面中的一个类别,而不是在文章详细信息页面中(我们可以在其中更新文章的内容和属性) .似乎将 Category 建模为 value 对象将无法实现这一点。

我能得到一些建议吗?谢谢

【问题讨论】:

    标签: domain-driven-design


    【解决方案1】:

    您可以用不同的方式表示类别,具体取决于您计划开发以解决特定问题的业务逻辑。

    例如,您可以拥有下一个限界上下文:

    1. CategoryManagement - 在此上下文中,类别可以表示为聚合根 - 在这里您将管理类别更改,验证类别数据的正确性以确保其在数据库中存储/更新有效,保护文章不变量(例如,确保在某个类别中同一文章不能被添加两次等)
    2. ArticleManagement - 在此上下文中,Article 将是一个 Aggregate Root,此处的 Category 可以表示为 ValueObject,例如,仅将其显示为编辑器的信息。

    【讨论】:

    • 嗯...这很有趣。谢谢@Elenka29 提供这个建议。这是否意味着,我将有两个域模型来表示 Category,一个是 Aggregate Root,另一个是 Value Object。唯一的区别是聚合根有一个 id,但值对象没有。在其他文章中没有看到这一点。
    • 是的,完全正确。在一个 BoundedContext 类别中将负责它的生命周期,而在另一个 Context 中 - 它只是 ValueObject 持有信息和其中一些必需的业务逻辑。我喜欢这篇 [文章] (culttt.com/2014/12/15/using-entities-different-bounded-contexts) 中描述这个想法的方式。 PHP中有示例,但总体思路很清楚,实体可以在不同的上下文中以不同的方式表示。
    • 谢谢@Elenka29,这真是一篇有趣的文章。在不同的 BoundedContexts 中作为不同类型的领域模型使事情变得非常灵活,
    【解决方案2】:

    阅读文章和书籍后,我很困惑Category应该建模什么类型的域模型。似乎将其建模为值对象或聚合根是合理的。

    这种混乱真的不是你的错。

    部分问题在于您的注意力集中在数据上;但从建模的角度来看,我们真正关心的是数据如何随时间变化。

    您在此处显示的信息(名称、描述、标题、内容)看起来都像是来自其他地方的信息副本——有人点击了保存按钮,然后就知道了!您存储该数据的副本。

    换句话说,这看起来像是数据库的数据模型。这很好——但这并不是 DDD 模式通常适用的那种问题。当您实际上不管理代码中的任何更改时,实体和值对象的区别以及将聚合用于生命周期管理的功能会失去很多。

    在文章“聚合”负责其自身更改的领域模型中,如何处理类别的线索将在描述当您获得新信息时文章如何更改的需求中。

    【讨论】:

    • 您好 VoiceOfUnreason,感谢您的建议。根据您在上一段中提到的内容,我是否可以理解在进行文章更改时应该根据其行为对哪个类别进行建模?例如,当我添加一篇新文章时,我可以创建一个新类别或选择一个现有类别。但我们将无法更新文章创建页面中的名称或描述。我们希望在类别管理页面中启用此更新功能。似乎将类别建模为聚合根更合理。如果我错了,请纠正我。
    • @Ben 一旦Category 被分配给Article。如果Category 发生变化,这些变化是否会反映在Article 上?如果他们这样做了,那么 Category 很可能是 AR,否则您将不得不更新所有 Article 实例。
    • 嗨@plalx,在示例代码中,Article 指的是Category 的列表。因此,如果我们从Category管理页面更改列表中第一个CategoryName,新的Name应该会反映在列表中的第一个Category中。不确定这对您是否有意义。
    猜你喜欢
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 2013-03-22
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    相关资源
    最近更新 更多