JAVA · 디자인패턴
CQRS 패턴
명령(Command)과 조회(Query)의 책임을 분리하는 CQRS 패턴입니다.
디자인패턴고급CQRSCommandQuery읽기쓰기분리
핵심 설명
명령(Command)과 조회(Query)의 책임을 분리하는 CQRS 패턴입니다.
Java code
import java.util.*;
// Command 모델 (쓰기)
interface Command {}
record CreateProductCommand(String name, int price) implements Command {}
record UpdatePriceCommand(String id, int newPrice) implements Command {}
// Query 모델 (읽기)
interface Query {}
record GetProductQuery(String id) implements Query {}
record SearchProductQuery(String keyword) implements Query {}
// 쓰기 모델
class ProductCommandHandler {
private final Map<String, int[]> writeStore = new HashMap<>();
String handle(CreateProductCommand cmd) {
String id = UUID.randomUUID().toString().substring(0, 8);
writeStore.put(id, new int[]{cmd.price()});
System.out.println("생성: " + id);
return id;
}
void handle(UpdatePriceCommand cmd) {
writeStore.get(cmd.id())[0] = cmd.newPrice();
System.out.println("가격 변경: " + cmd.id());
}
}
// 읽기 모델 (비정규화된 뷰)
record ProductView(String id, String name, int price) {}
class ProductQueryHandler {
private final Map<String, ProductView> readStore = new HashMap<>();
void sync(String id, String name, int price) {
readStore.put(id, new ProductView(id, name, price));
}
ProductView handle(GetProductQuery query) {
return readStore.get(query.id());
}
List<ProductView> handle(SearchProductQuery query) {
return readStore.values().stream()
.filter(p -> p.name().contains(query.keyword()))
.toList();
}
}학습 팁
CQRS를 사용하면 읽기 모델을 조회 패턴에 최적화(비정규화)할 수 있습니다. 이벤트 소싱과 함께 사용하면 시너지가 큽니다.
주의할 점
모든 시스템에 CQRS가 필요한 것은 아닙니다. 읽기/쓰기 패턴이 크게 다를 때만 도입하세요. 복잡성이 증가합니다.
자주 묻는 질문
CQRS 패턴란 무엇인가요?
명령(Command)과 조회(Query)의 책임을 분리하는 CQRS 패턴입니다.
CQRS 패턴 학습 시 주의할 점은 무엇인가요?
모든 시스템에 CQRS가 필요한 것은 아닙니다. 읽기/쓰기 패턴이 크게 다를 때만 도입하세요. 복잡성이 증가합니다.
Continue Learning
Java 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.