如何在领域驱动设计中实施无周期约束



我还是DDD新手。在域模型中,我有一个Component的聚合,它可以由子组件组成,也可以本身是另一个父Component的子组件。换句话说,我有一个组件层次结构。

需要两个操作:AddSubComponent()AddToParent()。在执行这两个操作时,如何强制执行层次结构中不存在循环的不变量?是否应通过域事件强制执行?或者只引用聚合中的父级和子级,然后在聚合本身中递归检查嵌套组件,如果操作会创建循环?

注意:我使用C#,并使用EF Core持久化域模型。

编辑我通过将每个组件视为一个集合来解决问题。每个人都有自己的父母和子女。

AddSubComponent(Component c)检查c是否已经是子组件,并在与组件的父组件和c的子组件进行检查后返回或仅添加c作为子组件。然后触发一个由应用层处理的域事件,以验证整个图是否包含循环,并调用c.AddToParent()

AddToParent(Component c)执行与上面的操作相同的逻辑,但只添加到父级,还触发一个域事件,该事件在应用程序层处理,也只调用parent.AddSubComponent()

通过这种方式调用任何方法都将确保仅用于聚合的原子一致性,并且整个层次结构的最终一致性由应用层确保。此外,上面的所有操作都封装在一个事务中。因此最终只保留有效的层次结构。

在这种情况下,我宁愿实现单向关系。当使用事件时,就像您提到的那样,这将是微不足道的,因为您可以在执行AddSubComponent之后发出事件,所以AddToParent将异步发生,作为一种反应。然而,在一个只保持状态的系统中生成事件并不是一件小事,因为您必须使用发件箱或CDC来避免不可靠的两阶段提交。

如果您只维护父级的子级列表,则没有必要这样做。当然,它可能不适合您的上下文,因为像确保组件只有一个父级这样的情况在模型本身中是不可能的,并且需要域服务,该服务会查询组件的父级以查看有多少。

您可以在方法本身中强制执行它。

添加子组件

在"添加子组件"方法中,检查要添加的组件是否已作为子组件或子组件的子组件存在。

添加到父项

将";AddSubComponent";将如上所述进行检查。

最新更新