도메인 주도 개발 시작하기 - 1 (도메인 모델 시작 - 1장)

겔로그·2023년 9월 29일
0
post-thumbnail

Spring Modulith를 이용한 사이드 프로젝트를 진행하기 이전에 DDD(Domain Driven Development)를 이해했으면 좋겠다는 생각이 들어 도메인 주도 개발 시작하기 라는 책을 읽고 정리하는 시간을 가져보고자 합니다.

이 글은 JPA 관련 내용은 전부 제외하였으며 DDD 관련 내용만 정리 및 요약하였음을 참고해주시면 감사하겠습니다.

1. 도메인 모델 시작하기

1. 도메인이란?

도메인이란 소프트웨어로 해결하고자 하는 문제 영역을 의미합니다.
도메인은 하위 도메인으로 나눌 수 있습니다.
도메인은 어려 개의 하위 도메인으로 구성됩니다.

예시. 온라인 서점을 만들고자 할 때

온라인 서점은 구현해야 할 소프트웨어 대상이자 소프트웨어로 해결하고자 하는 문제 영역입니다. 우리는 지금부터 온라인 서점을 도메인으로 볼 수 있습니다.

온라인 서점 시스템에는 상품 조회, 구매, 결제, 배송 추적 등의 기능들이 필요합니다. 이러한 기능들을 만들기 위해서는 상품 주문, 결제, 회원, 배송과 같은 도메인의 하위 도메인이 필요합니다.

온라인 서점 도메인의 하위 도메인을 간단하게 나누어 보면 다음과 같습니다.

그림1. 도메인은 여러 하위 도메인으로 구성

소프트웨어가 도메인의 모든 기능은 제공하지 않으며, 외부 업체 또는 소프트웨어를 연동하여 사용할 수 있습니다.

2.도메인 전문가와 개발자 간 지식 공유

  • 개발 이전에 요구사항을 올바르게 이해하는 것이 중요합니다.
    • 가장 단순한 방법은 개발자와 도메인 전문가가 직접 소통하면서 개발을 진행하는 것입니다.
    • 이해관계자와 개발자 모두 도메인 지식을 갖추고 소통하는 것이 좋습니다.

3. 도메인 모델

특정 도메인을 개념적으로 표현하는 것을 도메인 모델(개념 모델)이라고 합니다. 도메인 자체를 이해하기 위한 개념 모델이기 때문에 다양한 방법을 통해 도메인 모델을 모델링할 수 있으며, 이해하는데 도움이 된다면 표현 방식이 무엇인지는 중요하지 않습니다.

그림2. 도메인 모델 - 객체 모델

코드로 작성하는 모델은 구현 모델이라 부르며 도메인 모델과 구현 모델은 서로 다릅니다. 하지만, 구현 모델이 도메인 모델을 최대한 따르도록 할 수 있습니다.

도메인 모델을 모델링하는 방법

  1. 객체 모델링 (그림 2 참고)
  2. 다이어그램 모델링(클래스 다이어그램, 상태 다이어그램)
  3. 계산 규칙이 중요할 경우 수학 공식을 활용
  4. 기타

구현 모델이 개념 모델을 최대한 따르도록 하는 예시

  1. 객체 모델 -> 객체 지향 언어를 이용한 구현 모델 기획
  2. 수학적인 모델 -> 함수를 이용한 구현 모델 기획

4. 도메인 모델 패턴

일반적으로 애플리케이션 아키텍처는 다음과 같이 네 개의 계층으로 구성됩니다.

표현 계층: 사용자의 요청을 처리하고 사용자에게 정보를 보여줌
응용 계층: 사용자가 요청한 기능을 실행합니다. 도메인 계층을 조합해 기능 실행
도메인 계층: 시스템이 제공할 도메인 규칙을 구현
인프라스트럭처 계층: 데이터베이스나 메시징 시스템과 같은 외부 시스템과의 연동을 처리

3. 도메인 모델 에서 말한 모델은 개념 모델이라면, 도메인 모델 패턴에서의 도메인 모델은 아키텍처 상의 도메인 계층을 객체 지향 기법으로 구현하는 패턴을 의미합니다.

public class Order {
	private ShippingInfo shippingInfo;

	public void changeShippingInfo(ShippingInfo newShippingInfo) {
		if (!state.isShippingChangeable()) {
			throw new IllegalStateException("can't change shipping in " + state);
		}
		this.shippingInfo = newShippingInfo;
	}

	public void changeShipped() {
		retrun state == OrderState.PAYMENT_WAITING || state == OrderState.PREPARING;
	}
	...
}

public enum OrderState {
	PAYMENT_WAITING, PREPARING, SHIPPED, DELIVERING, DELIVERY_COMPLETED;
}

해당 코드에서는 Order, OrderState라는 도메인 모델에서 주문과 관련된 중요 업무 규칙을 구현했다는 점을 중점적으로 봐야 합니다. 주문 변경이 가능한 시점에서 주문 변경이 된다는 핵심 규칙을 구현한 코드는 도메인 모델에만 위치하기 때문에 규칙이 변경/확장되는 경우 다른 코드에 영향을 덜 주고 변경 내역을 모델에 반영할 수 있게 됩니다.

5. 도메인 모델 도출

도메인에 대한 이해 없이 개발을 시작하는 것은 매우 어렵습니다. 구현을 시작하기 위해서는 다음과 같은 과정이 필요합니다.

  1. 요구사항을 정의
  2. 관련자와의 소통
  3. 1,2를 바탕으로 한 도메인 모델 초안 작성

도메인을 모델링할 때 기본이 되는 작업은 모델을 구성하는 핵심 구성요소, 규칙, 기능을 찾는 것입니다. 해당 부분은 요구사항에서 출발합니다.

요구사항을 통해 클래스를 정의하고 각 클래스는 어떤 데이터로 구성할지, 어떤 행위(method)를 할지 정의할 수 있습니다.

요구사항을 토대로 점진적으로 만들어 나간 구현 모델은 도메인 전문과나 다른 개발자와 논의하는 과정에서 공유하며 요구사항 정련을 진행합니다. 이러한 과정을 문서화할 경우 소프트웨어 지식을 쉽게 공유할 수 있습니다.

6. 엔티티와 밸류

개념 모델에서 구현을 위해 도출한 모델은 크게 엔티티와 밸류로 구분할 수 있습니다.

엔티티

식별자를 가지는 객체입니다. 엔티티의 식별자는 바뀌지 않고 고유하기 때문에 엔티티는 식별를 통해 같은지 쉽게 구분할 수 있습니다.

식별자는 주로 다음과 같이 생성합니다.

  • 특정 규칙에 따라 생성
  • UUID 사용
  • 값을 직접 입력
  • 일련번호 사용(DB autoincrement 등)

밸류 타입

밸류 타입은 개념적으로 완전한 하나를 표현할 때 사용합니다. 온라인 쇼핑 시스템에서 수신자의 의미로는 다음과 같은 값들을 가질 수 있습니다.

배송 정보를 예시로 들어보겠습니다.

public class ShippingInfo {
	private Receiver receiver;
    private Address address;
}

public class Receiver {
	private String name;
    private String phoneNumber;
}

public class Address {
	private String address1;
    private String address2;
    private String zipCode;
}

배송 정보에서는 수신자의 의미로 수신자 명, 수신자의 전화번호를 가질 수 있으며 주소의 의미로 zip code와 같은 값을 가질 수 있습니다.

이렇게 두 개 이상의 데이터가 하나의 의미를 가질 때 밸류 타입을 사용할 수 있지만 꼭 두 개 이상의 데이터를 가져야하는 것은 아닙니다. 의미를 명확하게 표현하기 위해 밸류 타입을 사용하는 경우도 있습니다.

밸류 타입 정의 종류

  • 같은 의미를 가진 두 개 이상의 데이터를 하나로 관리할 때 정의
  • 의미를 보다 더 명확하게 표현하기 위해 정의

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

set 메서드는 도메인의 핵심 개념이나 의도를 코드에서 사라지게 하는 특징이 존재합니다. 또한, set 메서드로 인해 도메인 객체를 생성할 때 온전하지 않은 상태로 생성할 수 있다는 문제가 존재합니다.

도메인 객체의 불완전한 상태를 방지하기 위해서는 생성자를 통해 필요한 데이터를 모두 받아야하며, 불변 밸류 타입으로 사용함으로서 외부에서의 도메인 객체 변경을 불가능하게 만드는 것이 좋습니다.

7. 도메인 용어와 유비쿼터스 언어

코드를 작성할 때 도메인에서 사용하는 용어는 매우 중요합니다.
전문가, 관계자, 개발자가 도메인과 관련된 공통의 언어를 만들고 이를 대화,문서, 도메인 모델, 코드 등 모든 곳에서 같은 용어를 사용할 경우 용어의 모호성을 줄일 수 있오 개발자는 도메인과 코드 사이에서 불필요한 해석 과정을 줄일 수 있습니다.

도메인에서 사용하는 용어의 의미를 명확하게 전달하는 영단어를 찾기 힘든 경우가 많은데 시간을 들여 찾는 노력이 필요하니 이 시간을 아까워하지 말고 도메인과 어울리는 단어를 선택하는데 공을 들여야 합니다.

profile
Gelog 나쁜 것만 드려요~

0개의 댓글