Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 关于CQRS的几个问题_Design Patterns_Orm_Cqrs_Maintainability - Fatal编程技术网

Design patterns 关于CQRS的几个问题

Design patterns 关于CQRS的几个问题,design-patterns,orm,cqrs,maintainability,Design Patterns,Orm,Cqrs,Maintainability,我目前正在研究CQR是否可以在构建特定系统时应用,并且有一些问题我很难找到答案 命令可用性/验证 用户对特定实体的操作通常不仅与用户的角色有关,还与该特定用户与该实体(如作者)的关系以及该实体的状态(公共、存档等)有关 在我看来,在CQRS中,用户操作映射到负责处理它们的命令,但不清楚如何确定哪些操作和命令可用 返回每个读取模型的可用命令列表似乎不合适,因为出于一致性的需要,我们必须检查仅与用户角色相关的命令(例如菜单项) 当然,在事务中,这些命令必须再次进行验证,以防其他用户更改状态使命令无效

我目前正在研究CQR是否可以在构建特定系统时应用,并且有一些问题我很难找到答案

命令可用性/验证 用户对特定实体的操作通常不仅与用户的角色有关,还与该特定用户与该实体(如作者)的关系以及该实体的状态(公共、存档等)有关

在我看来,在CQRS中,用户操作映射到负责处理它们的命令,但不清楚如何确定哪些操作和命令可用

返回每个读取模型的可用命令列表似乎不合适,因为出于一致性的需要,我们必须检查仅与用户角色相关的命令(例如菜单项)

当然,在事务中,这些命令必须再次进行验证,以防其他用户更改状态使命令无效)

对需求变更的抵制 根据我的经验,维护一个逻辑冗长、有太多类/表绑定到特定业务对象的系统是一场噩梦

在CQR中,一个特定的业务实体可能有多个读取模型。当需要更改该实体时,还应修改所有相关的读取模型

对于可维护性,有必要以某种方式将它们关联起来,以便在重构时可以很容易地看到

在相关的注释中,拥有大量过度特定的命令也会导致可维护性问题——我正确地假设每个用例一个命令应该工作得最好

读取不修改域模型的模型和命令 在CQRS中,命令应该更新读取模型,同时用户可以访问它的旧版本

在我的脑海中,有两种特殊情况会引起这个问题

首先,有些命令不会修改域模型本身(可能只是状态),而是执行一些涉及第三方系统/框架/电子邮件等的操作,在某些情况下,这些命令可能需要相当长的时间才能运行

正如我在这里看到的,我们需要一个结合了域模型和命令执行状态的读取模型。此读取模型可用作当前正在处理的项目的历史记录或列表

其次,一些命令会产生一个结果。当命令成功完成时,需要向用户显示此结果,在某些情况下,必须在一段时间后丢弃,甚至是一个文件。因此,必须有一种方法将这些命令的结果存储在数据库中,并将它们与特定的命令实例相关联。换句话说,有一个临时读取模型

读取模型表vs内存缓存
我的想法也是正确的,使用二级ORM缓存(对于查询结果),不需要为读取模型设置数据库表,但ORM可以在第一次执行查询时生成它们,缓存结果,并在更改模型实体时自动使它们失效。这种方法似乎是实施CQRS界面/模式的良好起点,但可以更改,并且作为一种奖励,它可以支持动态投影(当用户选择要查看的列等时)。

总体而言,我不确定您具体提出的问题,所以我会尽力回答这些问题。我希望这有帮助。如果我没有抓住你问题的重点,我会澄清的——请告诉我

命令可用性/验证

我不确定您对这一部分的问题是什么,但基本上您的用户行为决定了您可以使用哪些命令。该命令对于该特定用户是否有效,可以由提交该命令的UI控制器(或任何机制)处理,也可以由接收该命令的域处理。该命令应包含足够的信息,以便域对其进行评估,然后更改其状态并引发事件

对需求变更的抵抗力

如果实体发生更改,并非所有相关的读取模型都需要更改——这实际上取决于读取模型的用途。维护读取模型的一些方法可以是对每个相关的读取模型集使用不同的模式,或者使用命名标准(例如ORDER_xxx)。我更喜欢前者,因为它更干净(至少从我的角度来看)

读取不修改域模型的模型和命令

命令并不总是用来更新读取模型。如果域中的业务规则引发处理和持久化的适当事件,则它们可以更新读取模型。发出命令并不意味着读取模型将被更新

如果您遵循CQS(和CQR),那么您的命令不应该返回结果。命令返回void。命令是指你告诉系统做些什么。您描述的是一个两步过程:发出命令,然后发出读取请求。读取请求很可能会产生“旧”数据(也就是说,在命令更新读取模型之前)。有几种方法可以解决这个问题。你可以投票,这不是一个很优雅的方式,但它是有效的。您可以在命令发出后将用户带到中间页面(“感谢您的订单,您想订购其他东西吗?”),然后当用户返回时,他们会看到更新的列表(因为命令现在已处理)。同样,这并不理想。但这就是最终一致性的本质。没有真正的答案——它实际上是由用户与系统的交互方式决定的

对于只更新状态或与第三方系统交互的命令,不能在用户等待完成的情况下脱机完成吗?我认为这是让您的系统反映用户将如何使用系统的另一种情况

读取模型表vs i