Architecture 如何组织实现CQR和DDD的依赖关系

Architecture 如何组织实现CQR和DDD的依赖关系,architecture,dependencies,domain-driven-design,cqrs,Architecture,Dependencies,Domain Driven Design,Cqrs,我尝试使用CQRS方法实现DDD服务。我没有使用事件源。 所以我有3层:应用程序层、基础结构层和域。许多人说,你们可以绕过域名进行查询,这是可以的。例如,假设这对我来说是必要的,因为性能问题 在忽略持久性之后,我在基础架构中实现了存储库。正如我在所有DDD实现和书籍中看到的,基础设施不应该依赖于应用层 那么我需要从存储库返回什么??如果DTO(读取模型、查看模型,实际上并不重要)是一个应用程序问题。将它们放在基础架构层会使应用程序与基础架构之间形成循环依赖关系,反之亦然。但是实现查询逻辑(如果我

我尝试使用CQRS方法实现DDD服务。我没有使用事件源。 所以我有3层:应用程序层、基础结构层和域。许多人说,你们可以绕过域名进行查询,这是可以的。例如,假设这对我来说是必要的,因为性能问题

在忽略持久性之后,我在基础架构中实现了存储库。正如我在所有DDD实现和书籍中看到的,基础设施不应该依赖于应用层

那么我需要从存储库返回什么??如果DTO(读取模型、查看模型,实际上并不重要)是一个应用程序问题。将它们放在基础架构层会使应用程序与基础架构之间形成循环依赖关系,反之亦然。但是实现查询逻辑(如果我使用Orm,它通过编写原始SQL进行查询)是一种不好的方法,因为为此目的,我们在基础设施中创建了存储库(这就是我们的方法)


另一种方法是从存储库加载聚合,然后将其转换为DTO,但由于我虚构的问题,这是不可能的。那么,如何以正确的方式处理这个问题呢?(这就是方法)

如果您想遵循Robert C.Martin的Clean Architecture,您应该将稳定的业务规则(高级抽象)与易变的技术细节(低级细节)分开,定义清晰的边界。您的源代码依赖项应该只指向内部,指向更高级别的策略。 要实现这一点,请使用依赖项反转原则。在您需要的层中为存储库定义接口。然后在基础架构层实现这些存储库


这意味着应用程序层不应该依赖于基础架构层。但是基础结构层可以依赖于应用程序层(基础结构可以使用应用程序)。

理想化的读取模型看起来很像缓存——您得到一个查询,您使用该查询计算缓存键,您返回使用该缓存键存储的字节

缓存未命中时会发生什么情况?然后,您必须查找数据,并计算返回的字节应该是什么

因此,您试图实现的是从持久存储中获取所需的状态,然后将该状态转换为调用方可以理解的序列化表示,而无需任何不必要的麻烦

例如,想象一个web API,其中客户端向您传递一个目标uri,并期望得到
application/json
响应。您的有状态数据存储是一些RDBMS,因此您可以使用现成的sql客户机执行查询,这将生成一个
ResultSet
。然后,您将使用类似DOM生成器的工具来构建树,在结果集中的行上迭代,并将数据列复制到树中。完成树之后,您将使用json库为树添加一个UTF-8表示。Tada,您已经得到了响应的表示,您可以将其保留在缓存中并返回到客户端

如果您对O/RM更熟悉,那么您可以定义一个内存中的对象表示,让O/RM负责创建结果的内存中表示,然后将其传递给JSON反序列化库

这里的要点是,这个转换组件需要理解如何解释从持久存储中检索到的值,以及如何在客户机可以理解的表示中表达该值——但您不需要实体。你“只是”接收信息并将其转换为其他信息

根据翻译的哪些部分是稳定的,哪些部分需要替换,这里可能有许多有用的设计。但是,翻译的实现不需要依赖于编写模型的实现细节

正如我在DDD的所有实现和书籍中看到的,基础设施 不应依赖于应用程序层

这根本不是事实。基础结构取决于应用层。查看沃恩·弗农的红皮书IDDD的图4.3(第124页)

例如,交叉服务(身份验证和授权、事务等)是在应用层定义的,而实现是在基础架构上

那么我需要从存储库返回什么??如果DTO(读取模型, 视图模型(实际上并不重要)是一个应用程序问题。 将它们放置在基础结构层上会产生循环依赖关系 从应用程序到基础架构,反之亦然。但是实施 查询逻辑(如果我使用Orm,而Orm是通过编写原始SQL进行查询的)是一个坏消息 方法,因为为此,我们在中创建了存储库 基础设施


如果您使用的是CQR,那么Querys的模型就不同了。存储库是命令模型的一部分。在Q模型中,您在应用层中定义所需的查询,返回客户端所需的对象(例如视图)。查询的实现在基础结构层,直接使用SQL。

好的,但在每个source\article\book中,DTO-都是一个应用程序问题,因此我们将它们放在其中。然后,如果您想直接返回DTO,它是来自实现和域的依赖项(因为接口就在那里)。我不完全理解这个想法,你能提供一段代码或一些git回购协议吗?据我所知,您讨论的是直接从某种ORM动态绑定数据?