kra*_*mir 4 domain-driven-design cqrs
假设读模型ProductCatalogueItem是从聚合/写模型构建的,与写模型分开存储,并包含每个可供销售的产品,并具有以下属性:
product_code,name,price,number_of_available_stock,short_description、description、...weight, length, depth, width, color,...并且,有两种观点:
product_code, name, price, number_of_available_stock,自然地,想到了两个 ViewModel:
ProductCatalogueListItem仅包含基本属性,ProductCatalogueItemDetails包含所有属性。现在,..有两个选择(我可以看到)。
因此,有两种读取模型,而不是一种,ProductCatalogueListItem并且ProductCatalogueItemDetails。并且,读取服务将有两种方法:
List<ProductCatalogueListItem> searchProducts(FilteringOptions),ProductCatalogueItemDetails getProductDetails(product_code)。并且,控制器直接返回这些模型(或者映射到传输层的 dto)。
这里的问题是过滤,..读取服务是否应该在不同的读取模型上执行搜索查询,而不是从方法调用返回的模型?因为,ProductCatalogueListItem 没有足够的信息来执行过滤。
读取服务有两种方法:
List<ProductCatalogueItem> searchProducts(FilteringOptions),ProductCatalogueItem getProduct(product_code)。并且,从 ReadModels 到 ViewModels 的映射是由上层(可能是控制器)完成的。
过滤没有问题,...但是,还有另一个问题,即离开域层的数据多于实际需要的数据。而且,控制器会随着更多的逻辑而增长。由于不同的传输技术可能有不同的控制器,因此映射代码可能会在这些控制器中重复。
根据 DDD/CQRS 或完全不同的方式,哪种组织职责的方法是正确的?
重点是:
首先,你的断言是错误的:
...读取模型 ProductCatalogueItem 是从聚合/写入模型构建的...
读取模型不知道聚合或任何有关写入模型的信息,您直接从数据库构建读取模型,返回 UI 所需的数据。
因此,视图模型是读取模型,它不涉及写入模型。这就是 CQRS 存在的原因:使用不同的模型(读取模型)来优化查询以返回客户端所需的数据。
我会尽力更好地解释自己:
CQRS 只是根据方法类型将一个对象分成两个。有两种方法类型:命令(任何改变状态的方法)和查询(任何返回值的方法)。就这样。
当您将此模式应用于应用程序的服务边界时,您将拥有写入服务和读取服务,因此您可以以不同的方式扩展命令和查询处理,并且还可以拥有两种模型。
但 CQRS 没有两个数据库,不是消息传递,不是最终一致性,不是从写入模型更新读取模型,不是事件源。您可以在没有它们的情况下执行 CQRS。我这样说是因为我发现你的断言中有一些误解。
也就是说,读取模型的设计是根据用户希望在 UI 中看到什么信息来完成的,即读取模型是视图模型,它们之间没有映射,它们都是相同的模型。您可以在下面的参考文献(3)和(6)中阅读相关内容。我认为这回答了你的整个问题。我不明白的是过滤问题。
(1)http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-source-agh/
(2) http://www.cqrs.nu/Faq/command-query-responsibility-segregation
(3) 《实现领域驱动设计》一书,作者:Vaughn Vernon。第 4 章:架构,“命令查询职责分离,或 CQRS”部分
(4) https://kalele.io/really-simple-cqrs/
(5) https://martinfowler.com/bliki/CQRS.html
(6) http://udidahan.com/2009/12/09/clarified-cqrs/