프로그래밍 노트/도메인 주도 설계(DDD)

[도메인 주도 설계] CQRS 적용하여 구현복잡도 낮추기

깡냉쓰 2023. 8. 28. 13:52
728x90
반응형

CQRS(Command Query Responsibility Segragation)은 상태를 변경하는 명령(Command)모델과 조회(Query)를 위한 모델을 분리하는 패턴이다. CQRS를 적용하면 어떤 장점이 있을까?

단일 모델의 단점

주문 내역 조회기능을 구현하려면 여러 애그리거트에서 데이터를 가져와야 한다.

  • Order: 주문 정보
  • Product: 상품 이름
  • Member: 회원 이름, ID

단일 모델을 이용한 조회 기능 구현

여러 애그리거트의 데이터가 필요한데 어떻게 구현해야할까?

  • 식별자를 이용하여 애그리거트를 참조하는 방식
    • 즉시 로딩(eager loading)과 같은 JPA 쿼리 최적화 기능을 사용할 수 없음
    • 한 번의 SELECT 쿼리로 조회 화면에 필요한 데이터를 구할 수 없음(성능상 문제 발생)
  • 직접 애그리거트를 참조하는 방식
    • 조회 화면 특성에 따라 같은 연관도 즉시 혹은 지연 로딩이 필요할 수 있으나 불가

시스템 상태를 변경할 때와 조회할 때 단일 도메인 모델을 사용하기 때문에 이러한 고민이 발생

  • 객체 지향으로 도메인 모델은 상태 변경 기능을 구현하는데 적합하다.
    • Order#cancel(), Order#changeShippingInfo()
  • 주문 상세 조회 화면처럼 여러 애그리거트의 데이터가 필요한 경우 고려할 게 많아 구현을 복잡하게 한다. (원인)

상태 변경을 위한 모델과 조회를 위한 모델을 분리하여 복잡도를 낮추자

CQRS

시스템이 제공하는 기능은 크게 두가지이다.

1. 상태를 변경하는 기능

  • 새로운 주문을 생성/배송지 정보 변경/회원 암호 변경/기능들이 포함
  • 현재 저장하고 있는 데이터를 변경하는 방식으로 기능 구현
  • 상태 변경 기능은 주로 한 애그리거트의 상태를 변경한다.
    • 주문 취소, 배송지 정보 변경 기능은 한 개의 Order 애그리거트를 변경한다.

2. 사용자 입장에서 상태 정보를 조회하는 기능

  • 주문 상세 내역 보기/게시글 목록 보기/배송지 정보 보기
  • 필요한 데이터를 읽어와 UI를 통해 보여주는 방식으로 구현
  • 조회기능에 필요한 데이터를 표시하려면 두 개 이상의 애그리거트가 필요할 때가 많다.
    • 주문 상세를 보여주려면 Order, Product, Member 애그리거트에 접근해야 한다.

상태를 변경하는 범위와 상태를 조회하는 범위가 정확하게 일치하지 않기 때문에 단일 모델로 구현하면 복잡도가 증가한다.
두 기능의 모델을 나눠서 구현하자.


  • CQRS는 복잡한 도메인에 적합하다.
  • 도메인이 복잡할수록 명령 기능과 조회 기능이 다루는 데이터 범위가 차이 난다.
  • Command / Query 서로 다른 기술을 이용해서 구현할 수 있다.

  • 상태 변경을 위한 명령 모델은 객체를 기반으로 한 도메인 모델을 이용해서 구현(도메인 로직 수행에 초점)
  • 조회 모델은 사용자에게 제공할 때 필요한 정보를 담고 있는 데이터 타입을 이용해서 구현(화면에 보여줄 데이터를 조회하는데 초점)

CQRS 장/단점

장점

  • 명령 모델을 구현할 때 도메인 자체에 집중할 수 있음
    • 명령 모델에서 조회 관련 로직이 사라져 복잡도가 낮아짐
  • 조회 성능을 향상시키는 데 유리
    • 조회 단위로 캐시 기술 적용 가능
    • 특화된 쿼리를 마음대로 사용 가능
    • 전용 저장소를 사용하여 처리량을 대폭 늘릴 수 있음
    • 조회 성능을 높이기 위한 코드가 명령 모델에 영향을 주지 않음단점

단점

  • 구현해야 할 코드가 많아짐
    • 단일 모델을 사용할 때 발생하는 복잡함 때문에 발생하는 구현 비용과 조회 전용 모델을 만들 때 발생하는 구현 비용을 따져봐야 함(유지 보수)
  • 더 많은 구현 기술이 필요

충분히 현재 상황을 고려한 후 도입을 고려하자

출처) 도메인 주도 개발 시작하기 - 최범균

728x90
반응형