我发现很难将CQRS/ES与“焦油坑外”的纸结构结合起来。
该体系结构包含4层:
在我的例子中,国家严重依赖于数据库。
考虑到CQRS/ES,我有一个决策引擎。从命令生成事件的决策引擎是Business,它必须是纯功能的。
当命令要求创建一个项目时,决策引擎选择接受或不创建事件CreateItem,只有当该项不存在时(示例简化)。
理论上,我应该将应用程序的状态作为参数传递给Business,以便做出相应的决定。
但是在数据库的情况下,我不能将数据库作为一个副作用的自由参数传递。我觉得我必须先执行查询,检查控件层中条目的存在,然后将数据库上的查询结果传递给Business,然后Business将返回一个事件。
其结果是,我有一些业务代码(与查询相关的业务代码和执行检查的业务逻辑)将位于控制层内。
就我所理解的“焦油坑外”文件以及CQRS/ES而言,这感觉是不对的。
对我来说,主要的问题似乎是国家是巨大的:它是整个数据库。
我的推理有什么问题?
发布于 2017-01-11 17:44:05
考虑到CQRS/ES,我有一个决策引擎。从命令生成事件的决策引擎是Business,它必须是纯功能的。
好的。
当命令要求创建一个项目时,决策引擎选择接受或不创建事件CreateItem,只有当该项不存在时(示例简化)。
也不错。
理论上,我应该将应用程序的状态作为参数传递给Business,以便做出相应的决定。
是的,完美。(注:“域的状态”多于“应用程序的状态”。此外,ddd还告诉我们,我们不需要整个域的状态,只需要对我们正在考虑的更改进行本地状态。)
但是在数据库的情况下,我不能将数据库作为一个副作用的自由参数传递。
这是正确的--所有与数据库的交互都应该发生在业务域之外(这只关心状态)。
我觉得我必须先执行查询,检查控件层中条目的存在,然后将数据库上的查询结果传递给Business,然后Business将返回一个事件。
阿。不完全--你不需要检查项目的存在,你需要检查它的状态,这不是完全相同的事情。
幸运的是,您正在使用ES;这确实简化了解释:不存在的实体的历史记录是空的。
因此,在本例中:您收到来自IO的命令。控件从应用程序状态获取适当的历史记录。调用该模型,将该历史记录和命令作为参数传递。模型返回事件(S),这些事件是在历史上此时运行的命令的结果。控件在应用程序状态下更新历史记录副本。
因此,快乐的道路:通信和CreateItem(x)到达。命令获取History(x),在本例中这是一个空的事件序列。被调用的模型,它从历史记录中看到项还不存在,并且业务不变量在其他情况下是满足的,它返回ItemCreated(x)事件的表示。
可选路径:通讯CreateItem(x)到达。命令获取History(x),在本例中,这是包括CreatedItem(x)在内的一系列事件。调用的模型,它从历史记录中看到该项先前已经创建,并拒绝命令(抛出异常,返回Error,返回空的事件集合)。
https://softwareengineering.stackexchange.com/questions/339981
复制相似问题