聚合Aggregate

什么是聚合:服务器

聚合是一个更大的封装单位,而不只仅是一个类。每一个事物的范围限定在单个聚合内。聚合组件的使用期被界限在整个聚合的生命周期中。
具体的,一个聚合将会处理命令,请求事件,并在其中封装一个状态模型,使其可以实现所需的命令验证,从而维护聚合的不变量(即业务规则)

聚合和聚合根之间有什么区别:框架

聚合造成对象关系的树或者图。而聚合根是树的“顶”,它整体上说明了聚合而且表明了剩余部分,它很重要由于他是全部通讯的地方。

我知道聚合是事务边界,但我真的须要在同一个事务中事务更新两个聚合。我该怎么办?设计

咱们应该从新思考以下:
   ①你的聚合边界
   ②每一个聚合的自责
   ③你怎么样才能够侥幸逃脱掉在读的一端或者在一个saga中
   ④你的领域的真实的非功能性的需求
   若是你写了一个解决方案,可是有两个或者多个的聚合以事务的方式耦合了,那么就说明你没有理解聚合

为何使用GUID做为ID是一个很好的作法?code

由于它们(合理)全局惟一,而且能够由服务器或客户端生成。

如何获取新建立的聚合的ID?对象

这是一个重要的看法,客户端能够生成本身的ID。
若是客户端生成了GUID而且将其放在建立聚合的命令中,这不是一个问题。不然,你须要从适当的读取端进行轮询,其中ID将以最终一致的时间框架出现。显然,这种是比在一开始就生成的方式要
脆弱的多的

咱们应该容许聚合间的引用吗?生命周期

从真实的“内存引用”的意义而言,固然是不能够的
在写方面,一个真实的从一个聚合到另一个聚合的内存引用是不对和禁止的。由于聚合的定义不容许到达他本身的外部(若是容许的话,那么意味着聚合再也不是事务边界,意味着我能够再也不去
思考维护其不变量的能力,他亦阻止了聚合的分隔)
使用字符串标识符引用另外一个聚合是能够的。在写方面是没有用的(由于标识符必须被视为不透明的值,所以聚合不能到达自身以外)。读的一端可能自由的使用这些信息来进行有趣的相关性

如何在一组聚合中验证命令?事件

这是一种再也没法经过聚合进行查询了的常见的反作用,有几个答案:
①客户端验证
②使用读的一端
③使用saga
④若是那些彻底不切实际,那么这就该考虑是不是聚合的边界不对

如何保证总体的引用完整性?事务

你如今仍在思考外来的关系引用,而不是聚合。看最后的那个问题。固然,记住仅仅由于是两个表的关系设计不易任何方式代表他们是两个聚合。聚合设计是不一样的

如何确保新建立的用户具备惟一的用户名?内存

这是一个常见的问题,由于咱们明确地不会在写方面执行交叉聚合操做。可是,咱们有不少选择:
①建立一个已经分配了用户名字的读取端。让客户端能够交互式的以键入用户名的方式查询读取端。
②建立一个响应式的saga来标记和停用那些不过是以用户名的读本建立的帐户(不管是不是极端巧合或者恶意的或者因为客户的错误)
③若是最终的一致性不够快,那么能够考虑在写的一端添加一个小的本地读取方面得标。确保聚合的食物插入该表

当我下订单时,如何验证客户ID是否真的存在?字符串

假设客户和订单都汇集在这里,很明显,订单的聚合是不能验证这个的,由于这意味着到达了聚合以外了
在事实以后检查,在一个记录了‘broken’订单的saga或者仅仅在一个读取端。毕竟,订单的最重要的事实彻底的记录它,大概任何关于订单的收件人的有趣的数据将会被复制到订单聚合中
(引用到用户去访问其地址是坏的设计,订单老是用来提供一个特定的地址,不管是否在将来客户改变他们的地址)
可以使用那些被记录在破损订单的数据意味着你有机会来拯救它,扭转局面---这使得比下列命令更有意义,由于违反外键约束!

如何使用单个命令更新一组聚合?

单一的命令是不能操做一组聚合的。
首先,问问本身你是否是真的须要一个命令更新多个聚合,是什么状况致使这个需求。
然而,你是能够这么作的。容许一种新的“批量命令”。在概念上包含你想要发布的命令以及一组您要发布的聚合(指定或明确指定)。写入段不够强大处处理这种批量操做,可是它能够建立相应
的”批量事件”。一个saga捕获这个事件,并在每一个指定的聚合上执行命令。当命令失败的时候,saga能够视状况调用rollback或者发送一封邮件。
这种方法有一些优势:咱们将批量操做的意图存储在事件存储中。saga自动回滚或等效。
尽管如此,不得不诉诸于此解决方案,这代表您的聚合的整体边界并不正确。你可能想考虑改变你的聚合边界,而不是为此创建一个saga。

什么是分片?

一种在多个写入端节点上分发大量聚合的方式。咱们能够很容易地分解聚合,由于它们彻底是自立的。
咱们能够很容易地分割聚合,由于它们没有任何外部引用。

聚合能够将事件发送到另外一个聚合?

不能够
你的聚合和命令处理器这些因素表明性的早已在代码中使这个想法没法表达,可是有一个更深层次的哲学缘由:
    回去从新读第一个问题“what's an aggregate?”
若是你设法规避命令处理程序,将事件推向另一个聚合,那么你将会失去聚合的参与验证的变化的机会。这就是为何咱们仅仅容许聚合器上的命令处理程序验证的命令建立事件。

我能从个人聚合中调用一个读取端吗??

不能够

在CQRS系统中咱们么发送email

在聚合以外的时间处理器,不要早命令处理程序中执行此操做,就像这个事件因为丢掉了与其余命令竞争而不会被持久化,因此email将会在一个虚假的前提下被发送。
相关文章
相关标签/搜索