TIL @Embbeded를 사용해 값 객체로 관리하는 방법의 장점?

Sunghun Kim·2025년 1월 2일

Jpa

목록 보기
10/10

Embedded 값 객체 예시

할인율(DiscountRate)을 엔티티에 포함시키되, @Embedded를 사용하여 별도의 값 객체(Value Object)로 관리하려고 한다.
값 객체로 분리하면 데이터 검증과 비즈니스 로직을 응집력 있게 유지하면서 코드 재사용성과 테스트 용이성을 높일 수 있다고 한다.

@Embeddable
public class DiscountRate {

    private int rate; // 할인율 값 (1~100)

    protected DiscountRate() {
        // JPA를 위한 기본 생성자
    }

    public DiscountRate(int value) {
        if (value < 1 || value > 100) {
            throw new IllegalArgumentException("Discount rate must be between 1 and 100.");
        }
        this.rate = value;
    }

    public int getRate() {
        return rate;
    }

    // 할인율 계산과 관련된 로직을 추가 가능
    public double apply(double originalPrice) {
        return originalPrice * (100 - value) / 100.0;
    }

@Embeddable 어노테이션 사용

Entity 적용 예시

@Entity
public class ProductEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Embedded
    private DiscountRate discountRate;

    protected Product() {
        // JPA를 위한 기본 생성자
    }

    public Product(String name, int discountRate) {
        this.name = name;
        this.discountRate = new DiscountRate(discountRate);
    }

    public String getName() {
        return name;
    }

    public DiscountRate getDiscountRate() {
        return discountRate;
    }
}

DiscountRate객체에 @Embedded 어노테이션 사용

MapStruct @Embedded와 같이 쓰기 예시

@Mapper
public interface ProductMapper {
    ProductMapper INSTANCE = Mappers.getMapper(ProductMapper.class);

    @Mapping(source = "discountRate.rate", target = "discountRate")
    ProductDTO toDto(ProductEntity entity);
}

위 형식 말고 주입형식으로 프로젝트에서는 사용해 볼 예정

장점

  1. 응집성: 할인율 검증과 비즈니스 로직을 DiscountRate 값 객체에 모아둘 수 있다.
  2. 재사용성: 여러 엔티티에서 같은 할인율 값을 사용하거나 공유 로직을 재활용할 수 있다.
  3. 테스트 용이성: DiscountRate 클래스를 독립적으로 테스트할 수 있다.
  4. 확장성: 할인율과 관련된 추가 기능(예: 최솟값/최댓값 변경, 유효성 검증 등)을 쉽게 추가 가능.
profile
BackEnd Developer!!

0개의 댓글