我目前正在研究一些遵循CQRS模式的概念验证代码,我无法找到一个令人满意的解决方案来解决我认为的问题。
系统根据具体情况计算市场变化对特定投资组合的影响。
投资组合可以包含一到几百个馆藏,并且市场场景是由用户针对特定请求即时预定义或定义的。
在最简单的形式中,这个问题的解决方案是在给定输入的情况下返回一些值的服务,但在CQRS情况下,在我看来,执行计算的部分(域)不应该被部分调用实际上返回数据(查询)。
考虑到像这样的系统很容易有多个投资组合,而且场景的数量也很高,我认为存储计算结果是没有意义的。
任何人都有解决这个问题的方法,或者可以指向一个解决类似问题的文章的方向?
答案 0 :(得分:5)
对我来说,CQRS的重点是创建两个域模型。一个优化用于使用命令更新数据,另一个优化用于使用查询读取数据。查询永远不会明显改变系统。将计算结果存储在排序缓存中是查询域模型的实现细节。只要缓存在时间上失效,也就是说,查询端最终与命令端一致,你就没事了。您当然应该控制应用程序中“最终”可接受的程度。
当您计算市场变化对投资组合的影响时,您正在对查询域模型执行查询。我没有看到为您感兴趣的场景创建查询类型的问题。
所以,总之,我认为你没有问题。请记住,你可以(shoud?!)隐藏查询处理程序和/或查询域模型中计算的复杂性。
答案 1 :(得分:5)
CQRS没有说您应该预先计算写入方面的所有内容。当系统状态通过命令更改时,将创建事件并且投影将侦听这些事件并创建可用于查询的模型。这个型号的外观以及它的用途取决于您。如果需要,您甚至可以创建系统的完整第3范式数据库表示的投影。
如果你在读取方面进行这些计算更实际,那么我认为这样做没有问题,只要可以丢失计算结果。
答案 2 :(得分:2)
如果您正在使用CQRS,因为您需要大规模的可扩展性,并且可扩展性围绕着读取这些计算的结果,您将需要存储在您的读取模型中预先计算的结果。
如果尺度/性能不是主要问题,那么我认为在运行中计算没有问题。
无论哪种方式,听起来计算器/计算本身都是读取模型的一部分,而不是域模型。听起来命令/写入方将包含一组输入,并且这些输入将通过计算器/计算投射到输出上。
答案 3 :(得分:2)
如果需要这些计算的结果来保持不变量,则只需要在写入模型中进行IMHO计算。不多也不少。
让我们使用(非常简化的)银行领域的例子: 如果您的不变量表明您不能提取超过您在帐户上的钱,而不是您应该计算余额(这是该帐户的提款和存款的总和)并且可能存储它(如果您有某种汇总)能够检查提款金额是否超过实际余额,但如果您的系统没有这样的不变量,那么计算是不必要的,并且很可能只应在系统客户端的读取侧计算余额。
我还想到你可能会问你是否可以使用读取方进行这些计算(如果它们计算量很大) - 这取决于。 大多数人会说,你不应该在写作方面使用阅读方,但即使是格雷格杨曾经说过,有时它是可以接受的。 请记住,在写入端使用读取端可能会使您的模型不一致,因为读取端数据可能已过期。