我在定义聚合边界(甚至可能是聚合根)以强制执行事务一致性规则时遇到了问题。让我首先描述问题域。
在我们的领域中,我们有一个包含预算计划的项目,而该计划又包含需要购买的数百个采购项目。这些项目中的一些被选中以构成购买任务。当发生这种情况时,项目应从预算计划移动到购买任务。项目的流程非常重要(需要对其进行审计以供以后审查),因此项目必须是一个实体并具有标识符。
我目前的设计将把购买任务作为聚合根,并且它将知道它的所有项目。我倾向于将预算计划排除在这个汇总之外,因为它包含了很多项目。但后来我开始怀疑自己。
Vaughn 描述认为,设计良好的聚合应该“基于真正的业务规则,这些规则要求在成功的数据库事务结束时,特定的数据必须是最新的”。在我的场景中,从预算计划中移动到指定购买任务的采购项应该从预算计划中的项目列表中删除。现在,如果我的汇总不包括预算计划和所有的数百个项目,我就不能强制执行这个规则。如果我确实将其包括在内,则聚合将变得越来越大,并且必须加载所有已编入预算的计划项目(数百项,也许数千项)才能成功验证。
由于购买项目也是一个需要跟踪和修改的实体,我认为应该是它自己的聚合根。然后,项目应该仅由其ID从预算计划和采购任务引用。这是正确的吗?
主要问题是:我应该如何定义聚合边界和根,以便能够在此域中强制执行事务一致性规则?
发布于 2015-09-03 20:48:15
项目计划可以是汇总的,预算的计划和购买任务可以是该集合中的实体。项目知道作出决策所需的所有数据。可以有相当多的数据,但是您可以使用延迟加载和自定义sql查询来优化内存和cpu的使用。
备选设计:编入预算的计划和采购任务可以是汇总的。您节省了一些内存,但当您在这两个聚合之间移动项时,现在需要同时修改两个聚合,这可能意味着您应该使用两个聚合之间的最终一致性。看这里,如何实现这一目标。
发布于 2015-10-11 20:40:32
当发生这种情况时,项目应从预算计划移动到购买任务。
真的吗?那种语言听起来很奇怪。
我希望预算计划能像购物清单一样。你计划你要买什么,然后当你到商店的时候,你开始检查清单上的东西。请注意,这与从列表中删除项目不同,这将涉及什么?把清单撕成碎片,这样你就可以在最后把它拿走,然后扔掉它。
请注意,由于列表仍然存在,所以您到达结帐时能够将购物车的内容与列表进行比较。
由于购买项目也是一个需要跟踪和修改的实体,我认为应该是它自己的聚合根。
采购项目实体需要在这个域中为自己执行哪些不变量?
https://softwareengineering.stackexchange.com/questions/295316
复制相似问题