cqs-patterns
CQS 및 CQRS 패턴 적용
클린 아키텍처는 상태를 변경하는 연산과 데이터를 반환하는 연산 간의 명확한 분리를 요구합니다. 이 기술은 .NET 응용 프로그램에서 명령 쿼리 분리(CQS) 및 CQRS를 구현하기 위한 패턴과 코드 예제를 제공합니다.
下载技能 ZIP
在 Claude 中上传
前往 设置 → 功能 → 技能 → 上传技能
开启并开始使用
测试它
正在使用“cqs-patterns”。 이 메서드를 CQS로 변환합니다: ```csharp public Order GetAndProcessOrder(int orderId) { var order = _repository.GetById(orderId); order.Process(); _repository.Update(order); return order; } ```
预期结果:
## CQS 규칙 준수 리팩터링
**명령 (상태 수정):**
```csharp
public void ProcessOrder(int orderId)
{
var order = _repository.GetById(orderId);
order.Process();
_repository.Update(order);
}
```
**쿼리 (데이터 검색):**
```csharp
public Order? GetOrder(int orderId)
{
return _repository.GetById(orderId);
}
```
**사용 방법:**
```csharp
var order = orderService.GetOrder(orderId);
orderService.ProcessOrder(orderId);
```
正在使用“cqs-patterns”。 주문 상태 업데이트를 위한 명령 생성
预期结果:
## 주문 상태 업데이트 명령
```csharp
public record UpdateOrderStatusCommand(
Guid OrderId,
OrderStatus NewStatus,
string? Reason = null
) : ICommand;
public class UpdateOrderStatusCommandHandler
: ICommandHandler<UpdateOrderStatusCommand>
{
private readonly IOrderRepository _repository;
private readonly IEventPublisher _publisher;
public async Task HandleAsync(UpdateOrderStatusCommand command,
CancellationToken ct)
{
var order = await _repository.GetByIdAsync(command.OrderId, ct);
if (order == null)
throw new OrderNotFoundException(command.OrderId);
order.UpdateStatus(command.NewStatus, command.Reason);
await _repository.UpdateAsync(order, ct);
await _publisher.PublishAsync(
new OrderStatusUpdatedEvent(order.Id, command.NewStatus), ct);
}
}
```
正在使用“cqs-patterns”。 CQRS를 언제 사용해야 하나요?
预期结果:
## CQRS 사용 시점
**CQRS에 적합한 경우:**
- 서로 다른 읽기/쓰기 패턴이 있는 복잡한 도메인
- 읽기가 많고 쓰기가 적은 시나리오 (보고 대시보드)
- 쓰기에 대한 감사 추적이 필요한 시스템
- 이벤트 소싱 시스템
- 별도 읽기 복제본이 있는 마이크로서비스
**CQRS는 복잡성을 추가합니다. 다음 경우 더 단순한 CQS를 고려하세요:**
- 단순 CRUD 연산이 지배적인 경우
- 읽기 및 쓰기 모델이 유사한 경우
- 소규모 팀이나 프로젝트인 경우
- 읽기와 쓰기 간 일관성이 중요한 경우
**메서드 수준에서 CQS로 시작한 후 요구 사항이 필요할 때 CQRS로 발전하세요.**
安全审计
安全All 60 static findings are false positives. The scanner misinterpreted documentation keywords (command, query), markdown code fences as backticks, and metadata fields as hardcoded URLs. The skill contains legitimate CQS/CQRS architectural documentation with C# code examples.
质量评分
你能构建什么
서비스 계층 메서드 설계
기존 서비스 메서드를 CQS 원칙에 따라 리팩터링하여 상태 변경 연산과 데이터 검색 쿼리를 분리합니다.
명령/쿼리 핸들러 구축
적절한 비동기 지원을 갖춘 확립된 MediatR 스타일 패턴을 따라 새로운 명령 및 쿼리 핸들러를 생성합니다.
읽기/쓰기 분리를 위한 아키텍처 설계
아키텍처 수준에서 CQRS를 적용하여 각 특정 concern에 최적화된 별도의 읽기 및 쓰기 모델을 설계합니다.
试试这些提示
이 메서드를 CQS 원칙에 따라 변환합니다. 상태를 변경하는 명령과 데이터를 반환하는 쿼리로 분리합니다:
```csharp
public User CreateAndReturnUser(string email, string name)
{
var user = new User { Email = email, Name = name };
_repository.Add(user);
return user;
}
```주문을 생성하기 위한 명령 핸들러를 생성합니다: - CustomerId 및 OrderItems가 포함된 CreateOrderCommand 수락 - 고객이 존재하는지 검증 - 항목이 포함된 Order 도메인 엔티티 생성 - 리포지토리에 지속 - OrderCreatedEvent 게시 - 주문 ID 반환
고객별 주문 검색을 위한 쿼리 핸들러를 생성합니다: - CustomerId, Page, PageSize가 포함된 GetOrdersByCustomerQuery 수락 - PagedResult<OrderSummaryDto> 반환 - 최적화된 SQL 쿼리 포함 - 총 개수 계산 처리
제품 카탈로그를 위한 CQRS 구현을 설계합니다: - 별도의 읽기 및 쓰기 모델 - 명령: CreateProduct, UpdatePrice, DiscontinueProduct - 쿼리: GetProduct, GetProductsByCategory, SearchProducts - 라우팅을 위한 디스패처 패턴 사용 - 단순 CQS보다 전체 CQRS가 가치를 추가하는 시점 고려
最佳实践
- 명령은 단일 작업에 집중하고 쿼리는 부작용 없이 데이터를 반환하는 데 집중하세요
- 제네릭 디스패칭 패턴을 활성화하기 위해 마커 인터페이스(ICommand, IQuery)를 사용하세요
- 도메인 모델을 터치하기 전에 명령을 검증하고 명확한 오류 메시지와 함께 빠르게 실패하세요
- 각 목적에 맞게 최적화하기 위해 읽기 모델(DTO)과 쓰기 모델(엔티티)을 분리하세요
避免
- 쿼리 핸들러에서 도메인 엔티티를 반환하면 읽기/쓰기 분리를 깨뜨립니다
- 도메인 모델이 아닌 명령에 비즈니스 로직을 추가하면 테스트 가능성을 저하시킵니다
- 최적화 요구 사항이 다를 때 동일한 모델을 읽기와 쓰기에 사용합니다
- 더 단순한 패턴으로 충분할 때 CQRS를 균일하게 적용하면 불필요한 복잡성을 추가합니다
常见问题
CQS와 CQRS의 차이점은 무엇인가요?
명령이 값을 반환할 수 있나요?
CQRS가 과도한 경우는 언제인가요?
CQS 규칙을 준수하는 코드를 어떻게 테스트하나요?
읽기와 쓰기에 동일한 데이터베이스를 사용해야 하나요?
디스패처 패턴이란 무엇인가요?
开发者详情
许可证
MIT
仓库
https://github.com/DoubleslashSE/claude-workflows/tree/main/Plugins/dotnet-tdd/skills/cqs-patterns引用
main
文件结构
📄 SKILL.md