我目前正在学习埃里克埃文斯的领域驱动-设计。聚合的概念对我来说是很清楚的,我觉得很有趣。现在我在想一个聚合的例子,比如:
BankAccount (1) -> (*)事务。
BankAccount
BigDecimal calculateTurnover();BankAccount是一个集合。为了计算营业额,我应该遍历所有的交易和汇总所有的金额。Evans假设我应该使用存储库只加载aggreagates。在上述情况下,可能会有一些事务处理,我不希望在内存中同时加载这些事务。
在存储库模式的上下文中,聚合根是唯一的对象>来自存储库的客户端代码加载。 存储库封装了对子对象的访问--从调用方的角度来看,它会自动加载它们,或者同时加载根对象,或者在实际需要时加载它们(与延迟加载一样)。
您对在DDD聚合中实现calulcateTurnover有什么建议?
发布于 2015-04-20 04:59:41
您成功地选择了一个非常有趣的例子:)
我实际上使用Account1->*Transaction向不熟悉它的人解释事件来源(ES)。
作为一名开发人员,我被教导(很久以前)使用我们现在所称的实体交互。所以我们有一个Customer记录,它有一个当前状态。我们以某种方式改变记录的状态(地址、税务细节、折扣等)。并存储结果。我们从来不知道发生了什么,但我们有最新的状态,因为这是我们的业务现状,这是很好的。当然,我们首先需要处理的问题之一是并发性,但是我们有方法来处理这个问题,即使不是很棒,但它“奏效了”。
出于某种原因,会计纪律不太相信这一点。为什么我们不简单地拥有Account的最新状态。我们将加载相关记录,更改余额,保存状态。奇怪的是,大多数人可能会对这一想法感到畏缩,但对我们其余的数据来说,这似乎是可以的。
会计域通过将更改事件注册为一系列Transaction条目来绕过这一问题。因此,如果您丢失您的帐户记录和最新余额,您始终可以运行所有的交易,以获得最新的余额。这就是事件来源。
在ES中,通常会加载聚合根(AR)的整个事件列表,以获得其最新状态。通常,在加载所有事件时,还会有一种机制来处理大量事件,从而导致性能问题:快照。通常只存储最新的快照。快照包含聚合的全部最新状态,并且仅包含应用快照版本后的事件。
ES的一个巨大优点是可以提出新的查询,然后简单地将所有事件应用到查询处理程序并确定结果。也许是这样的:“我有多少客户在过去的一年里已经两次移动了”。非常武断,但使用“传统”方法,答案很可能是,我们将从今天开始收集这些信息,并在明年发布,因为我们还没有保存CustomerMoved事件。使用ES,我们可以搜索CustomerMoved事件并在任何时候得到结果。
这让我回到你的例子。您可能不希望加载所有事务。相反,储存“营业额”,并计算它在前进。如果“周转率”是一个新的要求,那么一次对所有ARs的一次性处理应该使它跟上速度。您仍然可以在某个地方拥有一个calculateTurnover()方法,但这是您不会经常运行的方法。在这种情况下,您需要加载AR的所有事务。
https://stackoverflow.com/questions/29721771
复制相似问题