gpt4 book ai didi

domain-driven-design - 如何处理(部分)依赖聚合根?

转载 作者:行者123 更新时间:2023-12-04 08:23:22 24 4
gpt4 key购买 nike

我有 Product 的域概念.
Product有一些GeneralDetails ,比方说:sku, name, description .
同时,Product有一些ProductCalculations会计师可以输入不同值的部分,例如 purchasePrice, stockLevelExpenses, wholeSalesPrice, retailPrice .

所以,到目前为止,Product看起来像:

class Product{
GeneralDetails Details;
ProductCalculations Calculations;

ChangeDetails(GeneralDetails details){}
Recalculate(ProductCalculations calculations{}

}

此设置将使 Product聚合根。但是现在,我想以产品经理可以输入/更新产品详细信息的方式拆分它,但随后会计师可以介入并独立更改给定产品的计算,而不会出现并发问题。
这将建议将其拆分为 2 个单独的聚合根。

但随后,删除 ProductDetails聚合必须意味着删除 ProductCalculations也应该以交易方式发生。

假设它们是 2 个聚合根,这意味着它们有 2 个独立的存储库,对应的 Delete方法,如何将其实现为原子事务?

我唯一能想到的就是在 ProductDetails 时引发事件被删除,有一个处理程序( DomainService),它使用一些特殊的存储库来处理多个聚合根上的事务。

这种方法是否存在问题和/或是否有更好的方法来处理它?

PS。
ProductDetails 时,我不能允许最终的一致性被删除。

PS2。
基于@Jon 的评论, DetailsCalculations create&delete 应该以如下方式同步: Details被创建/删除, Calculations也应该创建/删除。
另一方面,它们的更新应该是完全独立的。

最佳答案

我几乎在每一点上都同意@plalx。不过,我想为讨论尽一份力。

我发现在单个事务中(在单个有界上下文中)创建两个或多个相关聚合通常需要很少的成本。毕竟,如果这些聚合不存在,但也不存在并发冲突,那么就没有争用,也没有太大的区别。此外,您不需要处理部分创建的状态(认为状态在聚合之间拆分)。可以使用最终一致性来做到这一点,并且在某些情况下这是一种更好的方法,但大多数时候并没有太大的好处。甚至 Vernon 在他的《实现领域驱动设计》一书中也提到这个用例是“打破规则的正当理由”。

删除多个聚合是另一回事。如果您删除并聚合另一个用户同时更新,会发生什么?随着您尝试在同一事务中修改/删除更多聚合,这种冲突的可能性会增加。这些聚合之间是否总是存在上游/下游关系?我的意思是,如果用户删除 AB也必须删除,让正在更新的用户 B没有“权力”或“声音”来取消删除,因为她正在向聚合状态提供更多信息?

这些是一个非常棘手的问题,并且大多数情况下您需要与领域专家讨论,并且很少有真正的场景是您无法承受最终一致性的答案。我发现在许多情况下最好放置一个“标志”,将聚合标记为“非事件”,通知将在一段时间后删除。如果没有具有足够权限的用户请求聚合再次变为事件状态,则将其删除。这有助于用户在错误地删除某些聚合时不会自杀。

您已经提到,如果有删除,您不希望用户花费数小时来修改一个聚合,但这是一个事务贡献不大的东西。不过,这非常依赖于整个架构。该用户可能已将聚合加载到她自己的内存空间中,然后发生删除。如果您在事务中删除也没关系,用户仍然在浪费时间。更好的解决方案可能是向用户发布一个触发某种推送通知的域事件,以便她知道发生了删除并且可以停止工作(或请求取消删除,如果您遵循这种方法)。

对于报表和计算,在很多情况下,这些“脚本”可以跳过兄弟聚合消失的记录,因此用户不会注意到缺少部分或尚未完全一致。

如果由于某种原因您仍然需要在同一个事务中删除多个聚合,您只需在应用程序服务中启动一个事务并使用存储库来执行删除,类似于创建案例。

所以,总结一下:

  • 当创建聚合时,“每个事务修改一个聚合”的规则并不重要。
  • 删除许多聚合(大多数情况下)效果很好,并具有最终的一致性,并且通常只禁用这些聚合,一次一个,比立即执行删除要好。
  • 与交易相比,通过适当的通知可以更好地防止用户浪费时间。
  • 如果确实需要在单个事务中执行这些操作,那么在应用程序中管理该事务是显式的。使用域服务来执行所有必需的操作(除了主要是应用程序关注的事务)将逻辑带回域层。
  • 关于domain-driven-design - 如何处理(部分)依赖聚合根?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51861198/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com