학습목표
“도메인 주도 설계” 방법에 대해서 학습합니다.
- 도메인 모델에 대해 이해한다.
- 도메인이란 무엇인가
- 도메인 모델 설계하기
- 도메인 영역의 주요 구성요소에 대해 학습한다.
- 엔티티, 밸류, 애그리거트, 리포지토리, 도메인 서비스에 대해 이해한다.
- 애그리거트와 바운디드 컨텍스트에 대해 학습한다.
- 애그리거트, 애그리거트 루트에 대해 이해한다.
- 바운디드 컨텍스트에 대해 이해한다.
도메인 모델
- 도메인이란 해당 비즈니스에서 다루는 분야이다.
- 개발자입장에서는 해결해야할 문제의 영역으로 본다.
- 도메인은 여러 하위 도메인으로 구성된다.
“고객이 원하는 상품을 어떻게 잘 제공할것인가?” 에 대한 고민이 있다면, 커머스라는 영역이 도메인이라고 볼 수 있다. 커머스 도메인을 만들기 위해서는 ‘주문’, ‘결제’ ,’배송’, ‘정산’ 등 하위 도메인이 필요하다.

도메인 모델 설계
유비쿼터스 언어
- 도메인 전문가, 개발자가 도메인과 관련된 공통의 언어를 만들어 사용한다.
- 도메인에서 사용하는 공통의 언어는 코드에도 그대로 반영이 되어야 한다.
- 공통의 언어를 사용함으로써, 코드의 가독성이 높아진다.
// 공통의 유비쿼터스 언어를 반영하지 않은 코드는 담당자들간 협업에 어려움이 있다. public enum OrderStatus { STEP1("주문 생성"), STEP2("주문 접수"), STEP3("주문 취소"), STEP4("주문 완료"), ; } // 공통의 유비쿼터스 언어를 반영한 코드는 코드가독성을 높인다. public enum OrderStatus { OPENED("주문 생성"), ACCEPTED("주문 접수"), CANCELLED("주문 취소"), CLOSED("주문 완료"), ; }
도메인 모델 도출
- 도메인을 구성하는 담당자들간 대화를 통해 도메인을 이해하고 이를 바탕으로 도메인 모델 초안을 만든다.
- 도메인을 구성할때, 기본이 되는 작업은 모델을 구성하는 핵심 구성요소, 규칙, 기능을 찾는 것이다.
주문 도메인을 구성하기 위해서는 아래와 같은 요구사항을 추출 할 수 있다.
- 최소 한 종류 이상의 상품을 주문해야 한다.
- 총 주문 금액은 각 상품의 구매 가격 합을 더한 금액이다.
- 주문은 배송지 정보를 포함해야 한다.
- 주문은 생성 → 접수 → 취소 → 완료의 상태를 가진다.
- 접수된 주문은 취소될 수 없다.
문서화
- 도출한 도메인은 다양한 형태의 다이어그램으로 문서화하여 담당자들간 공유할 수 있다.


도메인 영역의 주요 구성요소
도메인 영역은 ‘엔티티’ ‘밸류’ ‘애그리거트’ ‘리포지터리’ ‘도메인 서비스’ 로 구성된다.
- 엔티티 (ENTITY)
- 고유의 식별자를 갖는 객체로 자신의 라이프 사이클을 가진다.
- 주문, 회원, 상품과 같이 도메인의 고유한 개념을 표현한다.
- 데이터와 함께 기능을 제공한다.
- 밸류 (VALUE)
- 개념적으로 하나의 값을 표현할 때 사용된다.
- 엔티티의 속성으로 사용된다.
- 애그리거트 (AGGREGATE)
- 연관된 엔티티와 밸류 객체를 개념적으로 하나로 묶은 것이다.
- 리포지터리 (REPOSITORY)
- 도메인 모델의 영속성을 처리한다.
- DBMS 테이블에서 엔티티 객체를 불러오거나 저장하는 기능을 제공한다.
- 도메인 서비스 (DOMAIN SERVICE)
- 특정 엔티티에 속하지 않은 도메인 로직을 제공한다.
- ‘할인 금액 계산’은 상품, 쿠폰, 회원 등 다양한 도메인들을 이용해서 구현하게 된다. 이렇게 도메인 로직이 여러 엔티티를 필요로 하면 도메인 서비스에서 로직을 구현한다.
애그리거트와 바운디드 컨텍스트
애그리거트
- 복잡한 도메인을 이해하고 관리하기 쉬운 단위로 만들려면, 상위 수준에서 모델을 조망할 수 있는 방법이 필요한데, 상위 수준에서 조망할 수 있게 도메인을 묶어주는 것이 애그리거트이다.



애그리거트 루트
- 애그리거트에 속한 모든 도메인 모델들은 일관된 상태를 유지해야 한다.
- 애그리거트 루트는 애그리트거트 전체를 관리하는 주체이다.
- 애그리거트 루트 엔티티는 애그리거트의 대표 엔티티로 애그리거트에 속한 객체는 애그리거트 루트 엔티티에 직간접적으로 의존한다.

리포지토리리의 애그리거트
- 애그리거트는 개념상 하나의 도메인 모델을 표한한다.
- 객체의 영속성을 처리하는 리포지토리는 애그리거트 단위로 존재한다.
// 리포지터리는 완전한 order를 제공해야 한다. Order order = orderRepository.findById(orderId); // order가 온전한 애그리거트가 아니면 // 기능 실행 도중 NPE같은 문제가 발생한다. order.getOrderLine();
바운디드 컨텍스트
- 도메인 영역의 경계를 의미한다.
- 도메인 영역의 경계의 기준은 유비쿼터스 언어를 사용했을때, 해당 용어의 개념이 달라지는 곳을 기준으로 경계를 나눈다.

도메인 모델은 특정한 컨텍스트 하에서 완전한 의미를 가진다.
같은 제품(PRODUCT)라도 카탈로그 컨텍스트와 재고 컨텍스트에서 의미가 서로 다르다.
이렇게 구분되는 경계를 갖는 컨테스트를 “바운디드 컨텍스트” 라고 한다.