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

2025. 4. 19. 18:58·📚 개발자의 서재/도메인 주도 개발 시작하기
해당 포스팅은 최범균 작가님의  도메인 주도 개발 시작하기 (P.46~56)를 읽고 정리한 글입니다.

 

엔티티와 밸류

밸류 타입

밸류 타입은 개념적으로 완전한 하나를 표현할 때 사용한다. ShippingInfo 클래스는 받는 사람과 주소에 대한 데이터를 갖고 있다.

public class ShippingInfo {
    // 받는 사람
    private String receiverName;
    private String receiverPhoneNumber;
    
    // 주소
    private String shippingAddress1;
    private String shippingAddress2;
    private String shippingZipcode;
    
    // 생성자.. Getter..
}

ShippingInfo 클래스의 receiverName 필드와 receiverPhoneNumber 필드는 서로 다른 두 데이터를 담고 있지만 두 필드는 개념적으로 받는 사람을 의미한다. 즉, 두 필드는 실제로 하나의 개념을 표현하고 있다. 비슷하게 shippingAddress1 필드, shippingAddress2 필드, shippingZipCode 필드는 주소라는 하나의 개념을 표현한다.

  • receiverName + receiverPhoneNumber → Receiver(받는 사람)
  • shippingAddress1 + shippingAddress2 + shippingZipCode → Address(주소)

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

public class OrderLine {
    private Product product;	// 주문할 상품
    private int price; 			// 가격
    private int quantity; 		// 개수
    private int amounts; 		// 각 구매 항목의 구매 가격
}

OrderLine의 price와 amounts는 int 타입의 숫자를 사용하고 있지만 이들은 '돈'을 의미하는 값이다. 따라서 '돈'을 의미하는 Money 타입을 만들어 사용하면 코드를 이해하는 데 도움이 된다.

  • price, amounts → Money(돈)
public class OrderLine {
    private Product product;	// 주문할 상품
    private Money price; 		// 가격
    private int quantity; 		// 개수
    private Money amounts; 		// 각 구매 항목의 구매 가격
}

 

밸류 타입의 또 다른 장점은 밸류 타입을 위한 기능을 추가할 수 있다. 

public class Money{
	private int value; 
    
    ... 생성자, getValue()
    
    public Money add(Money money){
    	return new Money(this.value + money.value);
    }
    
    public Money multiply(int multiplier){
    	return new Money(value * multiplier);
    }
}

 

Money를 사용하는 코드는 이제 '정수 타입 연산'이 아닌 '돈 계산'이라는 의미로 코드를 작성할 수 있다.

public class OrderLine {
	
    private Money price; 
    private Money amounts;

    private int calculateAmounts(){
        // return price * quantity; 단순히 전수 타입 연산이 아닌
        return price.multiply(quantity); // 돈 계산의 의미
    }
}

 

밸류 객체의 데이터를 변경할 때는 기존 데이터를 변경하기보다는 변경한 데이터를 갖는 새로운 밸류 객체를 생성하는 방식을 선호한다. 이런 타입을 불변이라고 표현한다. 밸류 타입을 불변으로 구현하는 여러 이유 중 가장 중요한 이유는 안전한 코드를 작성할 수 있기 때문이다. 불변 객체는 참조 투명성과 스레드에 안전한 특징을 갖고 있다.

 

두 밸류 객체를 비교할 때는 모든 속성이 같은지 비교한다.


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

set메서드는 도메인의 핵심 개념이나 의도를 코드에서 사라지게 한다. 예를 들어 changeShippingInfo()가 배송지 정보를 새로 변경한다는 의미를 가졌다면, setShippingInfo() 메서드는 단순히 배송지 값을 설정한다는 것을 의미한다. completePayment()는 결제를 완료했다는 의미를 갖는 반면에 setOrderState()는 단순히 주문 상태 값을 설정한다는 것을 의미한다. set메서드는 필드값만 변경하고 끝나기 때문에 상태 변경과 관련된 도메인 지식이 코드에서 사라지게 된다.

 

set메서드의 또 다른 문제는 도메인 객체를 생성할 때 온전하지 않은 상태가 될 수 있다. 즉, 안에 필드값이 채워지지 않은채 생성될 수 있다. 도메인 객체가 불완전한 상태로 사용되는 것을 막으려면 생성 시점에 필요한 것을 전달해 주어야 한다. 즉, 생성자를 통해 필요한 데이터를 모두 받아야 한다. 생성자로 필요한 것을 모두 받으므로 다음처럼 생성자를 호출하는 시점에 필요한 데이터가 올바른지 검사할 수 있다.

 

불변 밸류 타입을 사용하면 자연스럽게 밸류 타입에는 set메서드 를 구현하지 않는다. set메서드를 구현해야 할 특별한 이유가 없다면 불변 타입의 장점을 살릴 수 있도록 밸류 타입은 불변으로 구현한다.


서비스를 구현할 때 밸류 객체를 어떻게 도출해야 할지 기준이 모호하게 느껴졌다. 하지만 글을 정리하면서, 밸류 객체를 판단하는 명확한 기준이 존재하지 않는 이유는 결국 각 도메인마다 의미가 다르기 때문이라는 점을 이해하게 되었다. 따라서 절대적인 기준에 의존하기보다, 해당 도메인에서 어떤 의미를 가지는지를 깊이 고민하고 그에 맞게 도출해 내는 연습이 필요하다는 것을 깨달았다.
저작자표시 비영리 변경금지

'📚 개발자의 서재 > 도메인 주도 개발 시작하기' 카테고리의 다른 글

[DDD] 아키텍처 개요 -1  (0) 2025.04.21
[DDD] 도메인 모델 시작하기 -5  (0) 2025.04.20
[DDD] 도메인 모델 시작하기 -3  (0) 2025.04.18
[DDD] 도메인 모델 시작하기 -2  (0) 2025.04.17
[DDD] 도메인 모델 시작하기 -1  (0) 2025.04.16
'📚 개발자의 서재/도메인 주도 개발 시작하기' 카테고리의 다른 글
  • [DDD] 아키텍처 개요 -1
  • [DDD] 도메인 모델 시작하기 -5
  • [DDD] 도메인 모델 시작하기 -3
  • [DDD] 도메인 모델 시작하기 -2
l'avenirJun
l'avenirJun
  • l'avenirJun
    오늘도 꾸준히 개발
    l'avenirJun
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 📚 개발자의 서재 N
        • 객체지향의 사실과 오해
        • Good Code, Bad Code
        • 도메인 주도 개발 시작하기 N
      • 🔧 트러블 슈팅
      • Java
      • Spring
      • 운영체제
        • 공룡책 학습
      • 알고리즘
      • GIT
      • 면접 지식
      • Spring 단기심화 2기
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    코드 계약
    매핑 구현
    캡슐화
    모듈화
    코드트리
    표현 영역
    티스토리챌린지
    DIP
    애그리거트
    메시지
    리포지터리
    유스케이스
    책임
    도메인 모델
    책임-주도 설계
    타입
    도메인 주도 개발 시작하기
    specification
    가독성
    애그리거트 루트
    객체지향의 사실과 오해
    코딩테스트
    오블완
    인터페이스
    역할
    추상화
    코딩트리조별과제
    good code bad code
    협력
    객체
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
l'avenirJun
[DDD] 도메인 모델 시작하기 -4
상단으로

티스토리툴바