Validation 如何将未完成的聚合根保持在无效状态?

Validation 如何将未完成的聚合根保持在无效状态?,validation,domain-driven-design,persistence,aggregateroot,Validation,Domain Driven Design,Persistence,Aggregateroot,我有一个聚合根,它需要处于有效状态才能在系统中正确使用。但是,构建聚合的过程足够长,用户可能会分心。有时候,用户只想配置这个大聚合的某些部分,然后保存他的工作并回家,明天他将完成聚合构造 我该怎么做?我的PM强制我们允许聚合具有无效状态,然后在使用它之前检查IsValid boolean 我个人走了另一条路:我使用构建器模式来构建聚合,现在我计划将构建器本身作为某种中介状态 我有一个聚合根,它需要处于有效状态才能在系统中正确使用。但是,构建聚合的过程足够长,用户可能会分心。有时候,用户只想配置这

我有一个聚合根,它需要处于有效状态才能在系统中正确使用。但是,构建聚合的过程足够长,用户可能会分心。有时候,用户只想配置这个大聚合的某些部分,然后保存他的工作并回家,明天他将完成聚合构造

我该怎么做?我的PM强制我们允许聚合具有无效状态,然后在使用它之前检查IsValid boolean

我个人走了另一条路:我使用构建器模式来构建聚合,现在我计划将构建器本身作为某种中介状态

我有一个聚合根,它需要处于有效状态才能在系统中正确使用。但是,构建聚合的过程足够长,用户可能会分心。有时候,用户只想配置这个大聚合的某些部分,然后保存他的工作并回家,明天他将完成聚合构造

我该怎么做

您有两个聚合——一个是用户可以按自己的速度编辑的“配置”。另一个是从配置副本构建的实时运行实例,但前提是该配置满足运行实例的不变量

顺便说一句,“正在运行”的聚合 应该重新编辑(事实上,这是经常发生的)。然后它可以变成 再次无效

这里有两个明显的选项:

  • 将每个正在进行的创建/更改过程建模为不同的聚合(甚至可能在不同的有界上下文中——可能是CRUD)。这允许您将主聚合从上下文验证中释放出来

  • 使用相同的聚合实例,但处于不同的状态。例如,您可能有一些字段为
    可选
    ,当聚合处于
    草稿
    状态时,这些字段可能为空,但当聚合处于
    发布
    状态时,这些字段不能为空。状态模式在这里可能很有用


所以我有两个完全相同的聚合(可以继承),一个没有验证,另一个有验证?我想我可以将它们保存在同一个表中,并为“isConfiguration”或“isWIP”标记集(原型模式)指定一列?顺便说一句,“正在运行”的聚合可能需要再次编辑(事实上,这是经常发生的)。那么它可能会再次失效。为什么不引入聚合被“激活”的概念呢。这样,在激活/使用时,它只需要处于特定的有效状态。“配置”聚合实际上可以是CRUD实体。很可能您的对象不是真正正确的聚合(从业务角度来看),因为它太复杂了。我会试着把它分成几个小部分。我不会添加一个答案,因为plalx和VoiceOfUnreason的答案涵盖了你的选择。我要补充的是,您可以使用更多的“告诉-不要问”方法,因为ARs应该通过其方法处理命令。您可以添加
Activate()
方法,该方法将在检查不变量后将聚合置于可用状态。当AR处于无效状态时,AR上的任何其他操作都将引发异常或将AR恢复为
非活动/草稿状态。您可以使用Saga来支持此过程。一个传奇将跟踪状态,直到您拥有创建有效AR所需的一切。