도메인 주도 설계

남예준·2025년 11월 12일

에반 에릭스가 만든 도메인 주도 설계

기본 어휘

개념핵심 질문역할 / 범위예시 (배달 서비스)
도메인 (Domain)“무슨 일을 하는 시스템인가?”비즈니스 전체 영역배달 서비스 전체 (주문, 결제, 배달 등)
바운디드 컨텍스트 (Bounded Context)- “이 개념은 어디서 유효한가?”
  • "같은 용어도 맥락에 따라 다른 의미를 가질 수 있다"
  • 같은 용어라도 다른 의미를 가질 수 있고 같은 대상이라도 다르게 지칠될 수 있다. | - 모델이 일관성을 가지는 구역 (보통 하나의 서비스 단위)
  • 의미상의 일관성
    | 주문 컨텍스트, 결제 컨텍스트, 배달 컨텍스트 |
    | 애그리거트 (Aggregate) | - “이 안에서 데이터 일관성을 보장해야 하는 단위는?” | - 컨텍스트 내부의 모델 단위
  • 로직 상의 데이터 일관성 | 주문(Order) + 주문상품(OrderItem) |

개요

지금까지 우리는 다른 도메인의 정보가 필요할 때 연관 관계로 가져오거나 Repository로 직접 호출했다.

또 어떤 경우는 EndPoint를 통해 RestTemplate이나 OpenFeign을 통해서 갖고 오는 경우도 있었을 것이다.

이러다보면 JPA 관련 문제를 맞닥뜨릴 수 있다.

단순한 프로젝트에서는 뭐 문제 없겠지만 복잡한 프로젝트에서는 불능할 것이다.

DDD가 필요한 이유

  • 비즈니스 영역이 너무 복잡한 경우 코드를 보는 것만으로 절대 비즈니스를 이해할 수가 없다.
  • JPA를 조금 더 잘 활용하기 위해

결론적으로는 복잡한 도메인을 효과적으로 다루고, 기술이 아닌 비즈니스 로직 중심으로 설계하기 위해!

변화

구현한 도메인을 효과적으로 활용

  • CRUD 컨트롤러
  • 도메인간 결합도를 줄이고 응집도를 높임

도메인의 경계를 명확히 설정

  • MSA로의 전환

도메인 중심의 설계 역량 강화

  • 복잡한 비즈니스 로직을 다룰 수 있게 됨

현재까지의 개발 방식

RDB에서는 연관 관계를 FK를 통해 달성하고 Join을 통해서 가져올 수 있다.

⇒ 객체 관점에서는 이슈가 될 수 있음. 객체지향적이지 않을 수도 있고 순환 참조의 가능성도 만들어 냄.

단순히 값이 필요해서 연관 관계를 맺는 건 안되는 말.

  • 종속적인 관계를 확인하고 이 영속성 전이의 범위를 명확하게 판단해야 함
  • 독립적인 관계는 영속성 전이가 미치지 않음. 예전에 주문한 상품의 내용이 바뀌었다고 덩달아서 바뀔 필요가 없음.

이걸 어떻게 해결해야 함?

바운디드 컨텍스트

컨텍스트는 회사 상황에 따라서 달라질 수 있음



각 컨텍스트 간 통신 방법

  • 응용 계층을 통한 도메인간 호출
    (facade를 통한 호출)


  • API를 통한 도메인간 호출(RestTemplate 등 WebClient)
  • 이벤트 리스너 등을 이용한 호출, 단순 정보가 필요할 때는 get, 변경이 필요할 때는 kafka나 메시지 브로커

애그리거트

객체들의 집합으로 데이터 영속성이 유지되어야 하는 집합이다.

애그리거트 루트는 기준이 되는 대표 객체라고 생각하면 된다.

컨텍스트보다 협의의 개념으로 컨텍스트는 한 개 이상의 애그리거트로 이루어진다.

애그리거트의 객체들은 라이프 사이클을 같이 함


애그리거트 루트의 존재 이유

  • 데이터의 일관성 유지
  • 변경 범위 (트랜잭션) 제어
  • 도메인 모델을 명확하게 만들기
  • 엔티티 간 직접 참조 방지
  • 데이터 저장소(Repository)와의 관계 정리

애그리거트 루트의 중요한 규칙

  • 외부에서 직접 OrderItem을 수정할 수 없다
    • 반드시 Order 객체를 통해서만 변경 ⇒ 응집도 증가
  • Order가 변경되면 내부의 OrderItem들도 함께 관리된다.(JPA Cascade, Dirty Checking)
    • Order가 삭제되면 OrderItem도 삭제
  • 데이터 일관성을 유지하기 위해 애그리거트 루트만 데이터 저장소를 통해 저장하거나 조회
    • OrderRepository는 있지만, OrderItemRepository는 없다.

순서

  1. 도메인을 나눔

  2. 서브 도메인 별로 바운디드 컨텍스트를 설정

  3. 나눈 도메인을 어떻게 구현할 것인지에 대해 애그리거트 등을 고려해보며 설

    도메인 모델 구성 요소:

    ├─ Entity (엔티티)
    ├─ Value Object (값 객체)
    ├─ Aggregate (집합체)
    ├─ Repository (저장소)
    ├─ Domain Service (도메인 서비스)
    └─ Domain Event (도메인 이벤트)

0개의 댓글