Domain driven design DDD(领域驱动设计)-大型聚合

Domain driven design DDD(领域驱动设计)-大型聚合,domain-driven-design,aggregate,Domain Driven Design,Aggregate,我目前正在学习Eric Evans的领域驱动设计。聚合的概念对我来说很清楚,我觉得它非常有趣。现在我想到一个聚合的例子,比如: 银行账户(1)-->(*)交易 BankAccount BigDecimal calculateTurnover(); 银行账户是一个集合。为了计算营业额,我应该遍历所有交易并汇总所有金额。Evans假设我应该使用存储库只加载aggreagates。在上述情况下,可能会有成千上万个事务,我不希望在内存中立即加载这些事务 在存储库模式的上下文中,聚合根是从存储库加载客户

我目前正在学习Eric Evans的领域驱动设计。聚合的概念对我来说很清楚,我觉得它非常有趣。现在我想到一个聚合的例子,比如:

银行账户(1)-->(*)交易

BankAccount
BigDecimal calculateTurnover();
银行账户是一个集合。为了计算营业额,我应该遍历所有交易并汇总所有金额。Evans假设我应该使用存储库只加载aggreagates。在上述情况下,可能会有成千上万个事务,我不希望在内存中立即加载这些事务

在存储库模式的上下文中,聚合根是从存储库加载客户端代码的唯一对象

存储库封装了对子对象的访问——从调用方的角度来看,它会自动加载它们,要么在加载根对象的同时,要么在实际需要它们的时候(如延迟加载)


您对在DDD聚合中实施Calulcate营业额有何建议?

正如您所指出的,在聚合中加载1000个实体不是一个可扩展的解决方案。正如Vaughn Vernon在他的系列文章中强调的那样,您不仅会遇到性能问题,而且可能还会遇到并发问题

您是希望每笔交易都能在
银行账户
合计中获得,还是只关心营业额

如果您只需要营业额,那么您应该在实例化您的
银行账户
聚合时建立此值。这可能是通过数据存储技术(例如,如果使用SQL,则为索引联接)有效地计算出来的。也许您还需要考虑将此作为数据存储中的预先计算的值(当您开始处理每个银行帐户的数百万事务时会发生什么)?

但也许您仍然需要域中可用的事务?然后你应该考虑有一个单独的<代码>事务< /C>存储库。


我强烈推荐阅读上文链接的沃恩·弗农(Vaughn Vernon)的聚合设计系列。

您已经找到了一个非常有趣的例子:)

实际上,我在向任何不熟悉事件来源的人解释事件来源时使用了
Account
1->*
Transaction

作为一名开发人员,我(很久以前)被教导使用我们现在可以称之为实体交互的东西。所以我们有一个
Customer
记录,它有一个当前状态。我们以某种方式更改记录的状态(地址、税务明细、折扣等)并存储结果。我们从来都不知道发生了什么,但我们有最新的状态,因为这是我们业务的当前状态,一切都很好。当然,我们首先需要处理的问题之一是并发性,但我们有办法处理这个问题,尽管不是很好,但它“起了作用”

出于某种原因,会计学科并不十分认同这一点。为什么我们不简单地拥有
帐户的最新状态
。我们将加载相关记录、更改余额并保存状态。奇怪的是,大多数人可能会因为这个想法而畏缩,但对于我们剩下的数据来说,这似乎还可以

会计领域通过将变更事件注册为一系列
交易
条目来解决这一问题。因此,如果您丢失了您的帐户记录和最新余额,您可以始终运行所有交易以获得最新余额。这就是事件来源

在ES中,通常为聚合根(AR)加载整个事件列表以获取其最新状态。通常,还有一种机制可以在加载所有会导致性能问题的事件时处理大量事件:快照。通常只存储最新的快照。快照包含聚合的完整最新状态,并且仅包含应用快照版本后的事件

ES的一个巨大优势是可以提出新的查询,然后将所有事件应用于查询处理程序并确定结果。可能是这样的:“我有多少客户在去年两次搬家”。相当随意,但使用“传统”方法,答案很可能是我们将从今天开始收集这些信息,并在明年提供,因为我们没有保存
CustomerMoved
事件。使用ES,我们可以搜索
CustomerMoved
事件,并在任何时候获得结果


这让我回到你的例子。您可能不希望加载所有事务。相反,存储“营业额”并随时计算。如果“营业额”是一项新的要求,那么一次性处理所有AR应该可以加快进度。您仍然可以在某个地方使用
calculateTurnover()
方法,但您不会经常运行该方法。在这种情况下,您需要加载AR的所有事务。

首先,感谢您快速响应。我最近订购了弗农的书,所以我很快就会读到,然后再回到这条线索上来。很高兴。如果你知道DDD的基础知识和术语,你可以从阅读我答案中链接的3部分PDF系列开始。