인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

tkwoo님의 프로필 이미지

작성한 질문수

EDA 기반 Microservice 구현 (with Hexagonal, DDD)

VO 클래스의 불변 필드 선언을 하지 않으신 이유?

작성

·

73

0

안녕하세요. 먼저 좋은 강의 감사합니다.

다름이 아니라, 강의자님께서 작성해주신 코드를 보면 모든 VO 클래스의 필드가 final 로 선언되어 있지는 않은 것으로 보입니다.

이와 같이 처리하신 이유가 단순히 강의 편의성을 위한 것인지, 혹은 다른 의도가 있는 것인지 궁금합니다.

 

제가 생각하기엔 아래와 같이 처리되어야 할 것 같습니다. (대여 서비스의 Item 클래스 예시)

/**
 * 도서 항목 VO
 */
@Getter
@Access(AccessType.FIELD)
@NoArgsConstructor(force = true, access = AccessLevel.PROTECTED)
@RequiredArgsConstructor
@Embeddable
public class Item {
    private final Integer no; //도서번호
    private final String title; //도서제목

    /**
     * 테스트용
     * @return
     */
    public static Item sample() {
        return new Item(10, "노인과 바다");
    }
}

 

추가로, RentalItem 은 엔티티로 재정의하셨다고 했는데, 코드상으로는 @Entity 없이 VO 처럼 취급되는 것 같습니다. 해당 부분까지 답변주시면 큰 도움될 것 같습니다.

감사합니다.

답변 2

1

han jeong heon님의 프로필 이미지
han jeong heon
지식공유자

강의자 한정헌입니다.

답변드리면 도메인 주도 설계에서 vo를 설계할 때 불변성을 유지하는 것이 매우 중요한 원칙 중 하나입니다. 따라서 private final로 필드를 선언하여 vo 내부 상태가 변경되지 않게 안전하게 함 좋은 설계 방법입니다. 하지만 이렇게 하면 내부에서 사용하는 객체,List,Map등이 있다면 이 또한 모두 불변으로 유지해야 하고 외부 객체 연동 시 불변성을 유지하는 코드 작성 등 객체 내부의 복잡성이 증가하고 추가 적인 처리 코드 작업이 필요합니다. 따라서 불변성을 유지하는 것의 중요성과 그것을 유지하기 위한 복잡성 추가 등을 트레이드 오프 할 필요성이 있습니다.

본 강의에서는 이러한 점을 고려하여 ,특히 가독성 측면에서 final처리하지 않는 것이 좋다고 생각했습니다.

그리고 rentalItem 은 이전 모델링 강의 에서 VO 로 선언했으나 overDued의 값이 변경됨으로 불변성을 잃음으로서 엔티티로 다시 개념 정의 한 부분입니다.

그런데 엔티티임에도 @Entity 처리를 안 한점을 지적 주셨는데 JPA의 @Entity와 도메인 주도 설계(DDD, Domain-Driven Design)에서의 엔티티(Entity)는 서로 다른 맥락에서 사용되는 개념입니다. 두 개념 모두 "엔티티"라는 용어를 사용하지만, 목적과 초점이 다릅니다.

  • DDD의 엔티티

    • 상태와 동작 : 데이터뿐만 아니라 행위(메서드)를 포함

    • 식별성(식별자을 기준으로 동일성 판단)

       

  • JPA의 엔티티

    • 데이터베이스와 동기화의 목적

    • 데이터베이스 테이블과 매핑됨을 의미

    • 반드시 기본키가 존재해야 함.(@id)

물론 현실적으로 데이터베이스와 매핑시 JPA의 @Entity와 DDD의 엔티티는 함께 사용되는 경우가 많습니다. 그렇지만 반드시 그래야만 하는 것도 아닙니다.

즉 비지니스 로직을 처리하기 위한 도메인 모델링 과 데이터 처리를 하기위한 or매핑과는 전혀 다른 영역이라 생각합니다.

따라서 RentalItem의 경우 초기에 도메인 모델링 관점에서 행위가 없기 때문에 vo로 설계했으나 overdued등의 값이 변경되어 불변성이 깨진다 판단하여 엔티티로 개념을 변경한 것이지만 역시 vo의 성격이 강하기 때문에 vo처럼 처리 했다고 생각하시면 될 것 같습니다.

tkwoo님의 프로필 이미지
tkwoo
질문자

트레이드 오프 관계임을 확인해주셔서 감사합니다.

그리고 엔티티라는 용어의 의미 차이가 있을 것이라고는 생각하지 못했는데, 짚어주셔서 감사합니다.

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다.

VO 클래스에서 필드가 final로 선언되지 않은 이유와 관련하여 질문해주셨습니다. 이것은 여러 이유가 있을 수 있는데요.
일반적으로 VO(Value Object)는 불변성을 중요시합니다. 불변성을 갖추기 위해 필드를 final로 지정하여 생성 시 값이 설정되고 변경되지 않도록 하는 것이 일반적인 패턴입니다.

다만, 강의나 코드 설명 시에 이러한 표준 패턴이 따르지 않으면, 교육적 목적에서 간소화된 예시를 제공하기 위해 의도적으로 생략될 수 있습니다. 예를 들어, 구현의 복잡성을 줄이고, 특정 개념에 집중하여 설명하기 위함일 수 있습니다.

RentalItem이 VO로 취급되는 부분에 대해, 강의나 코드를 기반으로 @Entity가 적용되지 않았다고 하셨는데, 이는 강의나 코드 설명의 일부분일 수 있습니다. 실제 구현에서는 VO와 Entity의 개념을 명확히 구분하여 사용하시는 것이 좋습니다.

관련하여 유사한 내용의 질문과 답변을 드리겠는데, 강의의 성격이나 강사님의 설명 의도를 반영하여 이해하시면 도움이 될 것 같습니다.

관련 질문 및 답변:

  1. Entity와 VO에 대해..

    • DDD에서 엔터티와 VO의 핵심적인 차이점에 대한 설명을 드리고 있습니다. 여기서 VO의 불변성에 대한 이야기를 들으실 수 있습니다.
  2. VO에 대해서 질문있습니다.

    • VO의 사용과 관련하여 자주 변경되거나 응집되는 값들에 대한 관리 방법에 대한 설명이 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

tkwoo님의 프로필 이미지

작성한 질문수

질문하기