# 1. 도메인 모델 시작하기
# 1.1 도메인이란?
- 소프트웨어로 해결하고자 하는 문제 영역
- 한 도메인은 다시 하위 도메인으로 나눌 수 있음
- ex) 온라인 쇼핑몰 -> {회원, 주문, 결제, 배송, ...}
# 1.2 도메인 전문가와 개발자 간 지식 공유
- 코딩에 앞서 요구사항을 올바르게 이해하는게 중유 → 개발자와 전문가가 직접 대화
- 이해관계자와 개발자도 도메인 지식을 갖춰야 함
- 반대로 전문가와 대화를 통해 원하는 요구사항을 찾는것도 중요
# 1.3 도메인 모델
- 도메인 모델을 표현할 때 중요한 부분에 따라 다양한 모델링 방법을 사용할 수 있음
- ex) 관계 → 그래프, 계산 규칙 → 수학 공식
# 1.4 도메인 모델 패턴
# 도메인 모델
- 아키텍처 상의 도메인 계층을 객체 지향 기법으로 구현하는 패턴
- 도메인의 핵심 규칙 구현
- ex) 주문 취소는 배송 전에만 할 수 있다
- OrderState로만 판단 가능하면 OrderState, Order 둘다에서 정의 가능
- 다른 정보가 더 필요하면 Order에서만
# 개념 모델과 구현 모델
- 개념 모델은 DB, 트랜잭션 처리, 성능 등에 대한 고려 없이 만든 결과물 → 순수하게 문제를 분석한 결과물
- 처음부터 완벽한 도메인을 만들기보다는 전반적인 개요를 알 수 있게 개념 모델 작성하기 → 나중에 바뀔 수도 있기 때문
# 1.5 도메인 모델 도출
- 도메인을 분석하고 제약사항들을 도출해내면서 도메인 모델을 점진적으로 구현
- 코드를 보기 전 상위 수준에서 정리한 내용을 문서화 해놓으면 도움이 됨 → 추후 코드를 보여 도메인을 깊게 이해 가능
# 1.6 엔티티와 밸류
- 엔티티와 밸류를 제대로 구분해야 도메인을 올바르게 설계하고 구현 가능
# 엔티티
- 고유한 식별자를 가짐
- ex) 주문번호
- 엔티티를 생성하고 속성을 바꾸고 삭제할 때까지 식별자는 유지 식별자가 같으면 → 동일한 엔티티
# 엔티티의 식별자 생성
도메인의 특징과 사용하는 기술에 따라 식별자 생성 시점이 달라짐
- 특정 규칙에 따라 생성
- UUID와 같은 고유 식별자 생성기 사용
- 값 직접 입력
- 일련번호 (시퀀스, DB의 자동 증가 칼럼)
# 밸류
- 개념적으로 완전한 하나
- ex)
@Getter
@AllArgsConstructor
public class Receiver {
private String name;
private String phoneNumber;
}
- 이를 통해 배송 정보를 다음과 같이 표현 가능
- ex)
@Getter
@AllArgsConstructor
public class ShippingInfo {
private Receiver receiver;
private String address;
}
- 꼭 2개 이상의 데이터를 가질 필요 없이 의미상 이해를 위해 밸류 타입을 사용할 수 있음
@Getter
@AllArgsConstructor
public class Money {
private int value;
public Money add(Money money) {
return new Money(this.value + money.getValue())
}
}
- add() 메서드와 같이 밸류 타입을 위한 기능도 추가 가능
- add() 메서드가 새로운 객체를 반환하는 것처럼 밸류 타입은 불변으로 구현하는 방식을 선호
- 파라미터로 전달받은 값을 변경하지 못하게 → 안전하게 사용 가능
# 엔티티 식별자와 밸류 타입
- 주문번호의 경우 식별자 타입으로 String 대신 OrderNo 밸류 타입을 사용하면 해당 필드가 주문번호라는 것을 알 수 있음
# 도메인 모델에 set 메서드 넣지 않기
- ex) completePayment() → setOrderState() : 상태 변경과 관련된 도메인 지식이 사라질 수 있음
- set을 사용함으로써 도메인 객체 생성 시 온전하지 않은 상태가 될 수 있음 → 생성자를 통해 생성 + 생성자를 호출하는 시점에 필요한 데이터가 올바른지 검사
- 클래스 내부에서 사용하기 위한 set 정의 시 private로 설정
# 1.7 도메인 용어와 유비쿼터스 언어
- 도메인에서 쓰는 언어를 코드에 반영해야 추후에 코드의 의미를 해석하기 쉬움
- ex)
// Before
public OrderState {
STEP1, STEP2, ...
}
// After
public OrderState {
PAYMENT_WAITING, PREPARING, ...
}
- 전문가, 관계자, 개발자가 도메인과 관련된 공통의 언어를 만들어 모든 곳에서 같은 용어를 사용하도록
- 영어 사용 시 알맞은 영단어를 찾도록 노력해야 함