book/도메인 주도 개발 시작하기

[DDD Start] 도메인 모델 시작하기

danuri 2023. 7. 6. 00:02

도메인 주도 개발 시작하기 책 정리

 

도메인 주도 개발 시작하기

실제 업무에 도메인 주도 설계(DDD)를 적용할 수 있도록 기본적인 DDD의 핵심 개념을 익히고 구현을 통해 학습할 수 있도록 구성한 DDD 입문서

www.hanbit.co.kr

 

도메인이란?

✅ 도메인

소프트웨어로 해결하고자 하는 문제 영역

도메인은 하위 도메인으로 나눌 수 있다.

ex) 온라인 서점 도메인 -> 주문, 결제, 배송, ...

 


 

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

✅ 요구사항

개발에 앞서 요구사항을 올바르게 이해하는 것이 중요하다.

 

✅ 요구사항을 올바르게 이해하려면?

개발자와 도메인 전문가가 직접 대화해야 한다.

도메인 전문가, 관계자, 개발자가 같은 지식을 공유하고 직접 소통할수록 도메인 전문가가 원하는 제품을 만들 가능성이 높아진다.

 


 

도메인 모델

✅ 도메인 모델

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

 

✅ 클래스 다이어그램

도메인이 제공하는 주요 데이터와 기능을 함께 보여줘서 도메인 이해를 돕는다.

 

클래스 다이어그램
https://brownbears.tistory.com/577

 

✅ 상태 다이어그램

도메인의 상태 전이를 모델링한다.

 

상태 다이어그램
https://sabarada.tistory.com/192

 

+) 클래스 다이어그램, 상태 다이어그램과 같은 UML이 아니어도,

도메인을 이해하는 데 도움이 된다면 표현 방식이 무엇인지는 중요하지 않다.

 

+) 하위 도메인마다 같은 용어라도 의미가 달라질 수 있기 때문에,

하위 도메인마다 별도로 도메인 모델을 만들어야 한다.

 

✅ 구현 모델

도메인 모델을 구현하기 위해,

구현 기술에 맞는 구현 모델이 따로 필요하다.

ex) 클래스 다이어그램(객체 기반 모델)은 객체 지향 언어를 이용해 구현 모델을 그릴 수 있다.

 

구현 모델
https://velog.io/@gun_123/도메인-모델-개념-모델과-구현-모델

 


 

도메인 모델 패턴

✅ 아키텍처 구성

일반적인 아키텍처는 네 개의 영역으로 구성된다.

1. 사용자 인터페이스 또는 표현: 사용자(외부 시스템)의 요청을 처리하고 사용자에게 정보를 보여준다.

2. 응용: 사용자가 요청한 기능을 실행한다. 업무 로직을 직접 구현하지 않으며 도메인 계층을 조합해서 기능을 실행한다.

3. 도메인: 시스템이 제공할 도메인 규칙을 구현한다.

4. 인프라스트럭처: 데이터베이스나 메시징 시스템과 같은 외부 시스템과의 연동을 처리한다.

 

✅ 도메인 모델 패턴

도메인 계층은 도메인의 핵심 규칙을 구현한다.

도메인 모델 패턴은 도메인 계층의 규칙을 객체 지향 기법으로 구현하는 패턴이다.

+) '도메인 모델'이란 용어는 앞서 말했듯이 도메인을 표현하는 개념 모델이지만,

도메인 계층을 구현할 때 사용하는 객체 모델도 '도메인 모델'이란 용어를 사용한다.

-> 앞으로 두 상황에 대해 모두 '도메인 모델'로 표현하겠다.

 


 

도메인 모델 도출

✅ 도메인 모델링

도메인을 모델링할 때 기본이 되는 작업은 [핵심 구성요소, 규칙, 기능]을 찾는 것이다.

이 과정은 요구사항에서 출발한다.

+) 요구사항으로부터 점진적으로 도메인 객체를 모델링하면 된다.

향후 도메인에 대한 이해가 증가하면서 코드를 수정할 수도 있다.

 


 

엔티티와 밸류

엔티티

✅ 엔티티

엔티티의 가장 큰 특징은 식별자를 가진다는 것이다.

식별자는 고유하고 불변하다.

 

엔티티의 식별자 생성

✅ 특정 규칙에 따라 생성

ex) 주문번호, 카드번호 등

 

✅ 고유 식별자 생성기

ex) UUID, Nano ID

 

✅ 값을 직접 입력

식별자를 중복해서 입력하지 않도록 사전에 방지하는 것이 중요하다.

 

✅ 일련번호 사용

주로 데이터베이스 제공하는 자동 증가 기능을 사용한다.

엔티티를 데이터베이스에 삽입해야 식별자를 알 수 있다.

 

밸류 타입

✅ 개념적으로 완전한 하나를 표현할 때

ex) String receiverName, String receiverPhoneNumber -> Receiver receiver

 

✅ 의미를 명확하게 표현하기 위해

그래서 밸류 타입이 꼭 두개 이상의 데이터를 가질 필요 없다.

ex) int price -> Money money

 

✅ 밸류 타입을 위한 기능을 추가

ex) price1 + price2 -> money1.add(money2)

 

✅ 밸류 타입은 불변 객체이다

불변 객체: 생성 후 그 상태를 바꿀 수 없는 객체

+) 참조 투명성

하나의 불변 객체는 변하지 않기 때문에, 여러 변수에 참조를 복사해도 된다.

가변 객체는 변할 수 있기 때문에, 참조로 복사하는 것은 위험하다. (하나의 참조를 갖는 여러 변수가 어디서 바뀔지 모른다)

+) Thread safe

불변 객체는 특정 스레드의 데이터가 변경될 우려 없이 접근할 수 있다.

즉, 베타 제어(mutual exclusion)를 할 필요가 없다.

 

엔티티 식별자와 밸류 타입

✅ 식별자를 밸류 타입으로

엔티티 식별자가 주문번호와 같이 특별한 의미를 지니는 경우,

밸류 타입을 사용할 수 있다.

ex) String id -> OrderNo id

 

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

✅ set은 단순하다

set은 단순히 값을 설정하는다는 의미이다.

만약 completePayment()와 같은 메서드가 아닌 setOrderState()와 같은 메서드를 사용하면,

상태 변경과 관련된 도메인 지식이 코드에서 사라지게 된다.

 

✅ 생성자를 사용하자

set을 사용하면 도메인 객체가 불완전할 수 있다.

생성자를 통해 필요한 모든 데이터를 전달하고,

생성자에서 private set 등을 통해 데이터가 올바른지 검사해서,

요구사항 면에서 완전한 객체가 생성되도록 하자.

 

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

✅유비쿼터스 언어

도메인 전문가, 관계자, 개발자가 사용하는 공통의 도메인 용어

코드를 작성할 때 도메인 용어는 매우 중요하다.

도메인 용어를 사용해 개발하게 되면, 도메인 용어와 개발 용어 간에 의미를 변환하는 과정을 줄일 수 있다.

 

✅ 영어

그러나 국내 개발자의 경우 영어를 사용하기 때문에,

도메인 용어를 영어로 해석하는 노력이 필요하다.

-> 쉽지 않은 일이지만 도메인 용어와 알맞는 영단어를 찾는 것은 중요하기 때문에 시간을 아까워하지 말자.

 


 

참고자료

https://ko.wikipedia.org/wiki/불변객체