首页 > 解决方案 > READ 和 WRITE 的通用服务 - CQRS + DDD

问题描述

嘿,我有一个聚合根,其中包含一些需要计算的属性 -总计。这些属性不会保存,但需要在播种时填充readDto以及在创建更新aggregateRoot 时为 EventStore填充事件

在读取写入部分之间有一个 COMMON 服务是否是一种好习惯,它将计算这些总数并将它们提供给 dto 或事件或任何需要它们的地方?

标签: eventsdomain-driven-designcqrsevent-sourcing

解决方案


有一个共同的服务

允许使用您通常用来实现 DRY 原则的任何有效技术(但请记住使用原则来缓和这一点)。

有时,这意味着在写入/决策过程和投影服务之间复制一个帮助文件。有时你甚至可以将它们编译成一个单独的帮助库。有时是动态语言中的一段代码,可以针对在决策过程、投影服务或读取器过程的上下文中水合的事件(或被折叠的一系列事件)的实例运行。

没有基本法则规定必须只有一件事(作为单一服务运行的编译代码)拥有该规则 - 对于初学者来说,如果您想在不停机的情况下部署该服务的更新会发生什么?

简而言之 - 没有硬性规定;任何这样一刀切的处方药都会有数百个例外。有点像企业范围的通用数据模型;)

我并不害怕通过使用单一服务来破坏 DRY 原则。

我真正关心的是使用常见的读/写内容是否违反 CQRS 模式。

这通常是合法的——读者和作者都观察事件流以推断(“折叠”)滚动状态。读者可能会暴露上下文信息,这些信息可用于驱动“用户”制定表示所需动作/状态转换的命令,这些命令必然具有一定程度的重叠。关键是决策本身应该只存在于写入端(但这非常符合命令通常不应该导致反馈的一般原则 - 通常它应该是通过任何验证等幂等处理的。作为既成事实的安全-驱动的双重检查)

其次,如果在读取部分使用逻辑违反 CQRS 模式。

一个通常同意的禁忌是在保持滚动状态的折叠中具有条件逻辑 - 这应该是简单的机械累积。

对于基于观察事件维护最终一致的只读视图的投影和/或非规范化器,通常将使用重叠的简单投影逻辑。如果该逻辑变得复杂,涉及事务等,那是一种设计气味-如果事件代表自然发生的事情而不是人为的,那么它们应该倾向于相对简单地映射/投影-您实际上应该只“索引”它们或以适合读者特定需要的形式排列它们。

如果您最终在投影系统中遇到复杂的流程,这表明您可能有多个不同的读者,并且可能应该为此考虑单独的投影(即有点像接口隔离原则)


推荐阅读