C# 架构精通 — ASP.NET Core 中的 CQRS(何时有帮助,何时有害)第9部分
Source: Dev.to
Introduction
CQRS 是现代 .NET 中最容易被误解的模式之一。
有的团队过早采用它,有的团队因为担心而完全回避。这两种错误都源于把 CQRS 当作框架选择,而不是一种架构策略。
在本第 9 部分,我们将解释 CQRS 真正是什么、何时能带来清晰、何时会对 ASP.NET Core 系统产生负面影响。
What CQRS Stands For
Command Query Responsibility Segregation
- Commands 改变状态
- Queries 读取状态
这两种职责被分离。
What CQRS Does Not Require
- 事件溯源(Event sourcing)
- 微服务(Microservices)
- 消息中间件(Message brokers)
- 独立数据库(Separate databases)
这些是可选的——并非 CQRS 的核心。
Traditional CRUD Services
CRUD 服务通常把以下内容混在一起:
- 读取
- 写入
- 验证
- 业务规则
- 映射逻辑
// ❌ CRUD service
class OrderService
{
Order Get(int id) { }
void Create(Order order) { }
void Update(Order order) { }
}
随着系统规模的增长,这会导致:
- 难以推理
- 难以优化
- 难以独立扩展
CQRS in Clean Architecture
- Commands 位于 Application 层
- Queries 位于 Application 层
- 基础设施实现持久化
- ASP.NET Core 将 HTTP 适配为 commands/queries
当边界已经存在时,CQRS 自然契合。
Commands
Commands 表示改变状态的意图。
public record CreateOrderCommand(decimal Total);
class CreateOrderHandler
{
public Task Handle(CreateOrderCommand command) { }
}
Characteristics
- 返回最少的数据(或不返回)
- 包含验证
- 强制业务规则
Queries
Queries 表示查询请求。
public record GetOrderQuery(int Id);
class GetOrderHandler
{
public Task Handle(GetOrderQuery query) { }
}
Characteristics
- 永不改变状态
- 可以使用优化的读取模型
- 常常绕过领域对象(有意为之)
When CQRS Is Beneficial
- 读写模型差异显著
- 查询性能至关重要
- 业务规则复杂
- 团队希望明确意图分离
- 正在使用垂直切片架构(VSA)
CQRS 在中大型系统中表现突出。
When CQRS Hurts
- 系统只是一个简单的 CRUD 应用
- 团队缺乏架构纪律
- 所有东西都变成 “handler” → 样板代码的负担超过价值
处理器激增的示例:
CreateUserCommandHandler
UpdateUserCommandHandler
DeleteUserCommandHandler
GetUserByIdQueryHandler
GetUsersQueryHandler
这可能会变成噪音而没有收益。
CQRS vs. MediatR
许多团队把 CQRS = MediatR,这是错误的认知。
- MediatR 是一个消息库和便利工具。
- CQRS 是一种设计决策和职责分离。
可以在不使用 MediatR 的情况下实现 CQRS。
CQRS Paired with Vertical Slice Architecture
每个切片包含:
- Command 或 Query
- Handler
- Validator
- Endpoint
Features/
└─ Orders/
├─ Create/
└─ GetById/
这降低了耦合度并提升了清晰度。
Adoption Checklist
在采用 CQRS 之前,先问自己:
- 读取和写入的演进是否不同?
- 性能是否真的成为问题?
- 领域复杂度是否在增长?
- 这会降低认知负担吗?
- 团队是否准备好遵守所需的纪律?
如果对任意问题的答案是 “否”,请推迟使用 CQRS。
Summary
- CQRS 不是灵丹妙药。
- 正确使用时: 明确意图,简化推理,优雅扩展。
- 错误使用时: 增加仪式感,拖慢团队,掩盖简单逻辑。
资深工程师懂得何时不使用它。