使用未分离的服务和存储库的 CQRS 真的会影响代码质量吗?
Is using CQRS with not separated services and repositories really affecting the quality of code?
我想问一个WEBApi架构。我的项目由几个 DDD、CQRS(无 ES)微服务组成。每个服务都有域、应用程序、基础架构和 UI 层。对于此示例,我将使用 BikeMicroservice。它在 UI 层中有 BikeController,它正在向 MediatR 发送命令或查询对象。在应用层中,我定义了处理程序(针对每个 C 或 Q),它们使用相同的 BikeService 对象来执行 C/Q。此外,BikeService 有 BikeRepository,它也使用 EF Core DbContext 对象执行命令和查询。
它是合适的 CQRS 组件吗?
我担心服务和存储库对象是否真的应该同时执行查询和命令。我在我的项目中观察到的唯一优势是更薄的控制器(只需发送查询或命令)。
如何升级微服务架构?
我应该将 DAL 和服务划分为例如使用 EF Core 的 BikeCommandRepository 和使用 Dapper 的 BikeQueryRepository 吗?
Martin Fowler describes several scenarios CQRS 可能使您受益的地方,以及一些会使事情复杂化的地方:
- CQRS fits well with event-based programming models. It's common to see CQRS system split into separate services communicating with Event Collaboration. This allows these services to easily take advantage of Event Sourcing.
- Having separate models raises questions about how hard to keep those models consistent, which raises the likelihood of using eventual consistency.
- For many domains, much of the logic is needed when you're updating, so it may make sense to use EagerReadDerivation to simplify your query-side models.
- If the write model generates events for all updates, you can structure read models as EventPosters, allowing them to be MemoryImages and thus avoiding a lot of database interactions.
- CQRS is suited to complex domains, the kind that also benefit from Domain-Driven Design.
这些是您在决定是否迁移到 CQRS 架构模型时应该评估的一些注意事项。
诚然,我不是资深软件开发人员,但最近几个月我对这个问题思考了很多,以下是我的观察和结论。
你认为 CQRS 比将一些 MediatR-consumed 类 前缀为 'commands' 和其他前缀为 'queries' 更复杂,这是非常正确的。
不幸的是,出于某种我不明白的原因,人们最近开始将 MediatR 等同于 CQRS,尽管 Jimmy Bogard 通常在 vertical slice architecture 的上下文中谈论 MediatR。
垂直切片
一般的好处来自这样一个事实,即您正在创建垂直切片,而不是使用传统的、分层的、服务密集型方法。这将用例彼此分离,减少了由于共享服务而导致的各种操作之间有问题的隐式依赖关系所引起的错误和复杂性的数量。
这是一个基本模式,您可以在简单的应用程序中实施而不会产生太多摩擦,并且可以说在任何地方都能提供一致的好处。
CQRS
另一方面,CQRS 需要为查询和命令创建并行数据访问结构,还可以选择创建并行模型。这固有地增加了复杂性和开销,并且通常,它提供了更简单的系统...
没有性能优势,因为您不必独立扩展读取和写入。
没有结构性好处,因为您不需要例如两个独立的开发团队独立处理读取模型和写入模型。
唯一适用的好处是更容易推理操作,因为它们是单独封装的,a.k.a。 command pattern。但是您已经从单独使用垂直切片中获得了好处。
(老实说,MediatR应该叫CommandR,它实现的是命令模式,而不是中介模式。)
因此,您应该问问自己,通过承担增加的复杂性和开销,您目前可以在特定用例中获得什么样的优势。
要点:
CQRS 并不是软件架构中的一个基本的、普遍关注的问题,例如SOLID 和(可以说)垂直切片是。
如果优势不明显,大多数查看该代码库的有经验的开发人员都会将其 CQRS 方面视为对代码质量的干扰和膨胀。
使用垂直切片和 MediatR 时,很容易在实际需要时实施 CQRS 关注点。这进一步降低了以 表面上 方式添加复杂性的理由。
所以,我个人的建议是:
继续使用相同的命令和查询存储库,放弃你正在做的想法 'CQRS',但作为语义细节继续调用那些 IRequest
类 作为 'command' 和 'query'.
当您遇到需要针对给定实体的查询针对您所面临的负载进行独立扩展的情况时,您会希望使用单独的数据库或 Dapper而不是 EF Core,and/or 一个不同的模型,然后为系统的那部分实现并行 CQRS 结构。并且,随着项目的发展,根据需要严格扩展 CQRS 结构。
当然,如果您只是想创建一个示例项目来探索 CQRS,那么请继续实施对您的学习体验有用的任何内容。
因为您已经在使用 entity framework 我不建议添加存储库模式,因为 Ef ORM 已经实现了存储库模式和工作单元。 MediatR 和 CQRS 应该足以让您通过。
在大多数情况下,仅当我们直接使用 SQL 和 ado.net 时才会使用存储库模式(以隐藏查询数据库的复杂性)。这篇文章 here 提供了更多信息,说明将 ORM 与存储库模式的抽象一起使用是多么不必要
我想问一个WEBApi架构。我的项目由几个 DDD、CQRS(无 ES)微服务组成。每个服务都有域、应用程序、基础架构和 UI 层。对于此示例,我将使用 BikeMicroservice。它在 UI 层中有 BikeController,它正在向 MediatR 发送命令或查询对象。在应用层中,我定义了处理程序(针对每个 C 或 Q),它们使用相同的 BikeService 对象来执行 C/Q。此外,BikeService 有 BikeRepository,它也使用 EF Core DbContext 对象执行命令和查询。
它是合适的 CQRS 组件吗?
我担心服务和存储库对象是否真的应该同时执行查询和命令。我在我的项目中观察到的唯一优势是更薄的控制器(只需发送查询或命令)。
如何升级微服务架构?
我应该将 DAL 和服务划分为例如使用 EF Core 的 BikeCommandRepository 和使用 Dapper 的 BikeQueryRepository 吗?
Martin Fowler describes several scenarios CQRS 可能使您受益的地方,以及一些会使事情复杂化的地方:
- CQRS fits well with event-based programming models. It's common to see CQRS system split into separate services communicating with Event Collaboration. This allows these services to easily take advantage of Event Sourcing.
- Having separate models raises questions about how hard to keep those models consistent, which raises the likelihood of using eventual consistency.
- For many domains, much of the logic is needed when you're updating, so it may make sense to use EagerReadDerivation to simplify your query-side models.
- If the write model generates events for all updates, you can structure read models as EventPosters, allowing them to be MemoryImages and thus avoiding a lot of database interactions.
- CQRS is suited to complex domains, the kind that also benefit from Domain-Driven Design.
这些是您在决定是否迁移到 CQRS 架构模型时应该评估的一些注意事项。
诚然,我不是资深软件开发人员,但最近几个月我对这个问题思考了很多,以下是我的观察和结论。
你认为 CQRS 比将一些 MediatR-consumed 类 前缀为 'commands' 和其他前缀为 'queries' 更复杂,这是非常正确的。
不幸的是,出于某种我不明白的原因,人们最近开始将 MediatR 等同于 CQRS,尽管 Jimmy Bogard 通常在 vertical slice architecture 的上下文中谈论 MediatR。
垂直切片
一般的好处来自这样一个事实,即您正在创建垂直切片,而不是使用传统的、分层的、服务密集型方法。这将用例彼此分离,减少了由于共享服务而导致的各种操作之间有问题的隐式依赖关系所引起的错误和复杂性的数量。
这是一个基本模式,您可以在简单的应用程序中实施而不会产生太多摩擦,并且可以说在任何地方都能提供一致的好处。
CQRS
另一方面,CQRS 需要为查询和命令创建并行数据访问结构,还可以选择创建并行模型。这固有地增加了复杂性和开销,并且通常,它提供了更简单的系统...
没有性能优势,因为您不必独立扩展读取和写入。
没有结构性好处,因为您不需要例如两个独立的开发团队独立处理读取模型和写入模型。
唯一适用的好处是更容易推理操作,因为它们是单独封装的,a.k.a。 command pattern。但是您已经从单独使用垂直切片中获得了好处。
(老实说,MediatR应该叫CommandR,它实现的是命令模式,而不是中介模式。)
因此,您应该问问自己,通过承担增加的复杂性和开销,您目前可以在特定用例中获得什么样的优势。
要点:
CQRS 并不是软件架构中的一个基本的、普遍关注的问题,例如SOLID 和(可以说)垂直切片是。
如果优势不明显,大多数查看该代码库的有经验的开发人员都会将其 CQRS 方面视为对代码质量的干扰和膨胀。
使用垂直切片和 MediatR 时,很容易在实际需要时实施 CQRS 关注点。这进一步降低了以 表面上 方式添加复杂性的理由。
所以,我个人的建议是:
继续使用相同的命令和查询存储库,放弃你正在做的想法 'CQRS',但作为语义细节继续调用那些
IRequest
类 作为 'command' 和 'query'.当您遇到需要针对给定实体的查询针对您所面临的负载进行独立扩展的情况时,您会希望使用单独的数据库或 Dapper而不是 EF Core,and/or 一个不同的模型,然后为系统的那部分实现并行 CQRS 结构。并且,随着项目的发展,根据需要严格扩展 CQRS 结构。
当然,如果您只是想创建一个示例项目来探索 CQRS,那么请继续实施对您的学习体验有用的任何内容。
因为您已经在使用 entity framework 我不建议添加存储库模式,因为 Ef ORM 已经实现了存储库模式和工作单元。 MediatR 和 CQRS 应该足以让您通过。
在大多数情况下,仅当我们直接使用 SQL 和 ado.net 时才会使用存储库模式(以隐藏查询数据库的复杂性)。这篇文章 here 提供了更多信息,说明将 ORM 与存储库模式的抽象一起使用是多么不必要