如何在 DDD 中对实体的当前状态进行建模

How to model an entity's current status in DDD

我正在努力掌握 DDD 背后的想法并将它们应用到我们拥有的一个宠物项目中,我有一些问题希望这里的人能够回答。

该项目是一个文档管理系统。我们遇到的特定问题与我们的系统处理的两个概念有关:DocumentDocumentStatus.

的概念

A Document 有许多属性(例如标题、作者等)。用户可以在其生命周期内更改 Document 的任何属性。

A Document 可能随时处于特定状态,例如 NEWUNDER_REVISIONREVISEDAPPROVED 等。对于每个状态,我们需要知道是谁对该状态进行了更改。

我们需要能够根据文档状态查询系统。一个示例查询是 "Get me all documents that are in the REVISED state".

"Get me all documents whose status has been changed by user X"

唯一需要在同一事务中更改 DocumentDocumentStatus 的时间是在创建 Document 时(创建文档并同时分配它的状态 NEW).

对于所有其他时间,UI 允许更新其中一个但不能同时更新两者(即您可以更改文档的 属性,例如作者,但不能更改其状态。)或者您可以更新其状态(从 NEWUNDER_REVISION)但不更新其属性。

我认为我们可以安全地认为 Document 是实体和聚合根。

我们对 DocumentStatus 是什么感到困惑。一种选择是使其成为 Document 聚合的值 Object 的一部分。

另一种选择是使它成为实体并成为其自身聚合的根。

我们还想提一下,我们考虑过各种 DDD 文档中描述的 CQRS,但我们认为这太麻烦了,尤其是考虑到我们需要对 DocumentStatus 执行查询这一事实.

欢迎任何指点或想法。

如果你只是记录当前状态,那么它很可能是一个值对象。

由于您正在将更多符合条件(如果不是识别)的数据组合到其中,并且您还打算查询这些数据,那么对我来说这听起来好像没有 DocumentStatus 是另一个,所以一个值对象没有多大意义,是吗?

它被识别为

  • 文档
  • 作者
  • 发生时间

此外,它在 previous DocumentStatus 的上下文中更有意义(如果你考虑的状态不仅仅是 NEWUNDER_REVISION).

对我来说,这清楚地排除了建模 DocumentStatus 作为值对象的可能性。

根据状态作为DocumentStatus的属性,并遵循一切皆对象(目前正在阅读 David West 的 Object Thinking),那么当然可以将其建模为值对象。

关注

你说你需要能够看到过去的状态变化,所以状态历史成为一个领域概念。一个简单的解决方案如下:

  • Document 实体中定义一个 StatusHistory
  • StatusHistoryStatusUpdate 个值对象的列表。
  • StatusHistory 中的第一个元素始终反映当前状态 - 确保在创建 Document 实体时将初始状态添加为 StatusUpdate 值对象。

根据状态历史记录需要多少额外的逻辑,考虑为历史记录本身创建一个专用值对象(甚至实体)。

坚持

您并没有真正说明您的持久层是什么样的,但我认为每个持久性机制都应该可以针对 StatusHistory 列表的第一个元素创建查询。例如,使用 map-reduce 数据存储,创建一个由 Document.StatusHistory[0] 索引的视图,并使用该视图实现您需要的查询。