胖领域事件或瘦领域事件

Fat Domain Events or thin domain events

我对发布领域事件的最佳方法有疑问。我有两个用例:

其中一个不变量是:

我设计了一个包含 Answer 个实体列表的聚合 Question,它 Question 构造函数我验证了不变性。

关于第一个用例,我的疑问与我应该发布的领域事件有关。

我的第一个方法是这个域事件:

public class QuestionCreated {
  private final String questionText;
  private final List<Answer> answers;
}

我对 answers 属性 感觉不太好,因为它是 Answer 实体的列表,但我不知道如何做得更好。

或者第二种方法,你会做两个域事件 QuestionCreatedAnswerCreated 并且当我创建一个问题时,聚合将发布一个 QuestionCreated 事件和一个 AnswerCreated 对于 answers 列表中的每个答案?

对于第二个用例,添加问题的答案,遵循聚合原则,我将使用新答案保存 Question 聚合。在这种情况下我也对要发布的领域事件有疑问,一个QuestionUpdated,类似于QuestionCreated,或者AnswerAdded只有答案信息。

谢谢!

由于一个问题不可能只有零个或一个答案,我认为在 Question(即 QuestionCreated)的“起源”事件中至少包含两个答案总体上更好。否则,您将不得不模拟一个具有零个或一个答案的原型问题,并确保永远不要将其视为 Question.

对于添加答案案例,通常最好避免 Updated 事件,因为领域事件建模的主要价值在于它们表达了上下文(例如“为什么”)的改变除了改变了什么。 Updated 事件不捕获该上下文。所以我肯定会使用 AnswerAdded 事件。

我会强烈考虑让 QuestionCreated 事件恰好有两个答案:

public class QuestionCreated {
  private final String questionText;
  private final Answer firstAnswer;
  private final Answer secondAnswer;
}

如果在创建时提供了 3-5 个答案,那么这些答案将作为 AnswerAdded 事件(或者其他相同但命名不同以捕获上下文 AnswerCreated)发出。通过以这种方式编码 QuestionCreated,我们确保没有办法用少于 2 个答案来表达创建事件(“使非法状态无法表示”......我们将挥手离开 null),并且我们也至少允许不分配 List.

的可能性