首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事件源-聚合建模

事件源-聚合建模
EN

Stack Overflow用户
提问于 2016-04-22 09:14:11
回答 1查看 600关注 0票数 1

两个问题1)如何对它们之间的聚合和引用进行建模2)如何组织/存储事件,以便能够有效地检索它们

以这个典型用例为例,我们有Order和LineItem (它们是聚合,Order是聚合根)和Product聚合。由于LineItem需要知道哪个产品,因此有两种选择1) LineItem直接引用产品聚合(这似乎不是一个最佳实践,因为它违反了聚合是一致性边界的想法,因为我们可以直接从订单聚合更新产品聚合) 2)那么LineItem只有ProductId。

看起来第二种选择是go...What的方法,你觉得呢?

然而,另一个问题出现了,这是关于构建订单读取/视图模型。在此订单视图模型中,它需要知道哪些产品是有序的(即ProductId、类型等)。典型的用例是报告,CommandHandler还可以使用此产品对象来执行逻辑,例如是否有太多特定的产品等。为了执行此操作,考虑到这些数据位于两个单独的聚合中,因此我们需要1+数据库往返。因为我们使用事件来构建模型,所以伪代码如下所示: 1)对于给定的订单id (guid,订单聚合id),我们加载它的所有事件;--第一个数据库访问2)然后构建一个订单聚合,然后我们知道在订单中引用了哪些ProductId;3)对于ProductIds列表,我们加载它的所有事件;--第二个数据库访问

如果我们构建一个非常大的对象图(许多不同的聚合),那么最终可能会有更多的数据库访问(每个访问都很慢)……你的想法是什么?

谢谢

EN

回答 1

Stack Overflow用户

发布于 2016-04-22 12:11:02

以这个典型用例为例,我们有Order和LineItem (它们是一个聚合,Order是聚合根),以及Product聚合。

订单聚合就像您所描述的那样有意义。"Product aggregate“更可疑;您是询问模型是否允许更改产品,还是告诉模型产品已经更改?

如果产品可以在未事先咨询订单的情况下更改,则LineItem不能包含该产品。引用产品(也就是ProductId)就可以了。

如果我们构建一个非常大的对象图(许多不同的聚合),那么最终可能会有更多的数据库访问(每个访问都很慢)……你的想法是什么?

对于读取、报告等,如果您不打算将新事件添加到历史中,一种可能的答案是提前完成缓慢的工作。异步进程侦听事件存储中的写入,然后将这些事件发布到总线。当观察到新事件时,订阅服务器构建新版本的报告,并缓存结果。(搜索关键词:cqrs)

当客户端请求报告时,您可以从缓存中给出一份报告。所有的工作都已经完成了,所以非常快。

对于命令处理程序,答案要复杂得多。业务规则应该在域模型中,所以让命令处理程序尝试验证命令(与域模型相反)有点不合常理。

命令处理程序可以加载产品以查看状态可能是什么样子,并将该信息与命令数据一起传递给聚合,但目前还不清楚这是不是一个好主意--如果客户端要发送一个要运行的命令,而您需要用产品数据充实订单命令,为什么不让命令直接将产品数据添加到命令中,并跳过中间人。

CommandHandler还可以使用此产品对象来执行逻辑,例如是否有太多特定产品等。

这个例子有点含糊,但是猜测一下:您正在考虑的情况是,如果可用库存不足以满足订单,就不能下订单。

对于现实世界的库存-仓库中的实体书-这可能是错误的方法。首先,模型本身是错误的;如果您想知道仓库中有多少产品,则应该查询仓库,而不是产品。其次,物理仓库不受模型的约束--在仓库聚合上调用addProduct方法不会导致产品神奇地出现在那里。

第三,它可能不能很好地匹配您的领域专家的需求。如果模型说仓库没有足够的产品,你认为利益相关者希望系统

  1. 告诉购物者在其他地方购买产品,或者...
  2. 接受订单,并联系供应商以获得新的发货。

提示:如果有疑问,请仔细检查amazon.com是如何做到这一点的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36783024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档