DDD中的域模型应该与持久性无关。
[CQRS指示我为我的读取模型中不需要的所有内容触发事件。 (并通过将我的模型拆分为一个写模型和至少一个读模型)。
ES指令我为所有更改状态的事件触发事件,并且我的聚合根必须处理事件本身。
对我来说,这似乎并不是一个永久的不可知论者。
那么,如何将DDD和CQRS / ES结合起来而又不会对该持久性技术造成严重影响呢?
读取模型也在DDD域模型中吗?还是在外面?
CQRS / ES事件是否与DDD域事件相同?
编辑:
我从答案中得到的是以下内容:
是的,对于ORM,域模型objecs的实现与使用ES的实现不同。问题是错误的解决方法。首先编写域模型对象,然后决定如何持久(更多事件,例如=> ES,更多数据,例如=> ORM,...)。
但是我怀疑,如果您没有事先做出此决定,您是否将能够使用ES(无需对域对象进行大的添加/更改),并且在未做出决定的情况下使用ORM也将造成极大的痛苦。 。 :-)
命令
归根到底,CQRS意味着您应该将读物与写物分开。
通常,命令到达系统并由某种函数处理,然后该函数返回该命令导致的零个,一个或多个事件:
handle : cmd:Command -> Event list
现在您有了事件列表。您只需要将它们保留在某个地方即可。一个执行该操作的功能可能如下所示:
persist : evt:Event -> unit
但是,这种persist函数纯粹是基础结构问题。客户端通常只会看到将Command作为输入且不返回任何内容的函数:
attempt : cmd:Command -> unit
其余部分(handle
,后跟persist
)是异步处理的,因此客户端永远不会看到这些功能。
查询
给出事件列表,您可以重播它们以便将它们聚合为所需的结果。这样的功能基本上看起来像这样:
query : target:'a -> events:Event list -> Result
给出事件列表和要查找的目标(例如ID),这样的功能可以将事件折叠成结果。
持续性无知
这是否强迫您使用特定类型的持久性?
这些功能均未根据任何特定的持久性技术进行定义。您可以通过
实现这样的系统从概念上讲,它[确实]迫使您从事件的角度考虑持久性,但这与ORM迫使您从实体和关系的角度考虑持久性没有什么不同。这里的意思是,将CQRS + ES架构与大多数实现细节分离非常容易。这通常是对持久性无知的[[足够
。