#01장 도메인 모델의 시작

최범균 저「DDD START!, 2016」를 읽고 정리하였습니다.

  • 다룰 내용

    • 도메인 모델

    • 앤티티와 밸류

    • 도메인 용어

도메인

  • 책 구매

    • 목차와 평가 보기, 장바구니담기, 쿠폰찾기, 카드결제/가상계좌입금, 배송추적

  • 이러한 기능을 가진 온라인서점은 소프트웨어로 해결하고자 하는 도메인 영역이 된다.

  • 도메인은 다시 하위도메인으로

    • 주문

      • 결제, 배송, 혜택, etc

  • (경우에 따라) 외부 시스템 이용

    • 결제 - 외부 PG

    • 배송 - 외부 물류

    • 즉, 도메인 밑에 서브도메인이 필요에 따라 변경이 될 수도

도메인 모델

  • 특정 도메인을 개념적으로 표현한 것.

    • UML이든 객체 관계도로 표현하든 개념적으로만 표현하면 된다. (아래 그림)

    • 사례: 주문 과정

      • 주문수량 설정 -> 배송지 입력 -> 결제수단 선택 후 계산 -> 주문 완료 -> 출발안했음, 배송지 변경 가능

    image-20211223110703141

  • 객체 뿐만 아니라 도메인을 나타낼 수 있다면, 이해와 지식 공유 도움되면 다른 대체제도 모두 가능하다.

    • e.g. 상태 다이어그램 (아래 확인)

      • 결제 여부에 따라 상품 준비

      • 출고가 완료되면 취소 불가

image-20211223111133178

도메인 모델 패턴

  • 가장 흔한 Application 아키텍처

    • 4 계층: 표현 - 응용 - 도메인 - 인프라(DB) (Layer Architecture 링크arrow-up-right)

      • 표현 - UI. 사용자/외부시스템 요청 처리하고 보여준다.

      • 응용 - 사용자 요청 기능 실행. 업무 로직 X. 도메인 계층 조합해서 기능 실행.

      • 도메인 - 도메인 규칙 구현.

      • 인프라 - DB나 메시징 외부 시스템 연동하여 처리

    • 예측: 주문- 주문, 계산, 배송

  • 어떤 코드가 도메인 계층에?

    • 사례: 주문 도메인 규칙

      • 규칙1: 출고 전에 배송지 변경 가능

      • 규칙2: 주문 취소는 배송전에만 가능

      • 아래는 반영 코드

  • 포인트: 주문과 관련된 중요한 업무 규칙을 주문 도메인 모델인 아래 2개의 객체에서 하고 있다는것.

  • 리팩토링: OrderState는 Order에 속한 데이터이다. 즉, 배송지 변경 가능 여부 판단 코드는 Order로 이동 가능.

개념모델 vs 구현모델

  • 문제를 분석하고 개념 모델로 결과물을 뽑아낸 뒤, 구현 모델로 전환한다.

도메인 모델 도출

  • 모델 도출하기 위해선, 기획서, USE CASEarrow-up-right, 사용자 스토리로 초안 만들기.

  • 모델링 기본 작업들

    • 핵심 구성 요소

    • 규칙

    • 기능

  • 주문 관련 요구사항

    1. 최소 한 종류 이상의 상품을 주문해야 한다 .

    2. 한 상품을 한개 이상 주문할 수 있다.

    3. 총 주문 금액은 각 상품의 구매 가격합을 모두 더한 금액 이다 .

    4. 각 상품의 구매 가격 합은 상품 가격에 구매 개수를 곱한 값 이다 .

    5. 주문할 때 배송지 정보를 반드시 지정해야 한 다 .

    6. 배송지 정보는 받는 사람 이름, 전화번호, 주소로 구성 된다 .

    7. 출고를 하면 배송지 정보를 변경 할 수 없다 .

    8. 출고 전에 주문을 취소할 수 있다 .

    9. 고객이 결제를 완료 하기 전에는 상품을 준비 하지 않는다 .

  • 이로 알 수 있는 4가지 기능

    • 이 기능들을 메소드로 추가할 경우

  • 2, 4 요구사항에 의해 주문 항목이 어떤 데이터로 구성될 지 알 수 있다.

    • OrderLine 객체 참고

  • 요구사항 1과 3은 Order와 OrderLine의 관계를 보여준다. 따라서 Order를 다음과 같이 변경.

  • ShippingInfo

  • 요구사항 5에 따라, Order를 생성 할때 OrderLine 뿐만 아니라 ShippingInfo도 함께 전달해야 한다.

  • 생성자에 반영

  • 요구사항 7, 8 (9번도 관련)

    • Enum 이용하여 상태로 표현하기

  • Order에 해당 요구사항을 적용하면,

    • 주목: isShippingChangeable -> verifyNotYetShipped

      • 시간이 흐르며 도메인을 더 잘 알았기에, 리팩토링

        • 배송지 정보 변경와 주문취소가 "출고전에 가능" 이라는 제약조건을 찾게되었기에~

Entity와 Value

  • 도출한 모델은 엔티티와 밸류로 구분 가능

  • 도메인 구현을 위해, 둘의 차이를 명확하게 이해해야 한다.

  • 여기선 Value를 '값'으로 사용하지 않을것.

![image-20211223180521665](D:\0 Google Drive\03 스터디 모임\DDD\1주차 발표.assets\image-20211223180521665.png)

엔티티

  • 식별자를 갖는다.

    • e.g. 주문번호 (orderNumber)

    • 배송지가 바껴도 주문번호가 바뀌지 않으므로, 식별자는 변경 x. 즉, 삭제될때 까지 유지.

  • equals와 hashCode를 구현하면 다음과 같다

엔티티의 식별자 생성

  1. 특정 규칙에 따라 생성

  2. UUID

  3. 값 직접 입력

  4. 일련번호 사용

  • 특정 규칙에 따라 생성

    • 사례: 아마존/알라딘 온라인서점

      • 주문번호, 운송장번호, 카드번호는 특정 규칙에 따라 생성

    • 흔히 사용 방법

      • 시간과 다른 값을 함께 조합

      • 2015년 05월 29일 09시 46분 44초

        • 20150529094644

      • 같은 시간에 생성시, 같은 식별자 만들어질 수 있으므로, 주의해야 한다.

  • UUID

    • e.g. java.util.UUID

  • 값 직접 입력

    • e.g. 사용자 아이디나 이메일

  • 일련번호

    • e.g. 시퀀스나 DB의 자동 증가 컬럼

    • 자동 증가 컬럼의 경우, 데이터를 삽입해야 값을 알수 있기에, 객체 생성시 식별자를 전달할 수 없다.

    • 4장에서 자세히

밸류 타입

  • 밸류 타입 = 개념적으로 완전한 하나를 표현

  • 사람과 주소에 대한 데이터

  • 밸류 타입에 따라, 쪼갤 경우

결과적으로 ShippingInfo는 이렇게 바뀐다.

또 다른 사례로 OrderLine에 밸류타입을 활용 해보자.

Money타입을 사용했기에 price나 amount가 금액을 의미함을 명확히 알 수 있다.

밸류 타입의 추가적 장점 - 밸류 타입을 위한 기능 추가 가능.

요약, 밸류 타입 = 코드의 의미 명확화 특징 - 기존 데이터를 변경하긴 보단, 새로운 객체 생성 선호하는 편임 불변 = 안전한 코드 작성 가능

line과 price의 값이 다르다.

![image-20211223185550393](D:\0 Google Drive\03 스터디 모임\DDD\1주차 발표.assets\image-20211223185550393.png)

발생 방지를 위한 추가 조치로

다만, Money가 불변이었다면, 이런 코드를 작성할 필요가 없었다.

엔티티타입 객체 비교는 식별자를 사용했다면, 두 밸류 객체는 모든 속성값들을 비교한다.

엔티티 식별자와 밸류 타입

  • 식별자는 단순한 문자열이 아니라 도메인에서 특별한 의미를 가지는 경우가 많다. (e.g. 주문 객체의 주문번호)

도메인 모델에 setter 메서드 넣지 않기

  • 고쳐야할것: 습관적 추가 = set 메서드

  • 의미적 차이

    • changeShippingInfo(ShippingInfo newShippingInfo): 배송지 정보 새로 변경

    • setShippingInfo(ShippingInfo shippingInfo): 배송지 값을 설정

  • 의미적으로 올바른 메서드명으로 써야한다.

set 사용시 문제코드

더 나은 코드

  • 생성자 호출 시점 데이터 유효 검사 가능

완성 코드

  • 여기서도 set 사용하잖아요!?

    • 접근 범위를 보자: private = 불변 밸류 타입

도메인 용어

  • 도메인 용어는 중요하기에 코드를 작성하는데 이를 이용해야 한다.

  • 결제대기중, 상품준비중, 출고완료, 배송중, 배송완료, 주문취소

    • 를 아래와 같이 표현하면?

  • 도미노 처럼

    • 다른 코드도 이상해 진다

  • 올바른 단어 선택: state vs status, kind vs type

  • 어렵지만, 시간 들여 찾아 적절한 단어를 고르자.

Last updated