Issues : 정적 팩토리 메소드 vs toEntity

박채원io·2024년 6월 4일

프로젝트를 할 때마다 객체 생성과 그 위치에 관해 고민이 되어서 이번 기회에 정리해 보았다.
먼저 new 가 아닌 정적 팩토리 메서드와 빌더 패턴을 사용해서 호출 시에 매번 새로운 객체를 생성하지 않도록 구현하였다.

▶️ 요청 DTO

요청 DTO는 클라이언트로부터 입력받는 데이터를 표현하는 객체이다. 이 엔티티를 생성하는 로직은 두 가지 경우로 나뉜다.

정적 팩토리 메소드 사용

  • 엔티티의 생성 로직이 복잡하거나 생성 방법이 자주 변경될 것으로 예상될 때
  • 엔티티 내에 정적 팩토리 메서드를 정의 (객체 생성이기 때문에 DTO에 정적 팩토리 메소드를 정의하는 것보다 엔티티 내에 정의하는 것이 적절함)
  • 엔티티의 생성 로직을 엔티티 내부에 캡슐화함으로써 엔티티의 생성 방법이 변경되더라도 서비스 계층의 코드 변경을 줄일 수 있다. 하지만 DTO가 엔티티의 생성 메서드에 의존하게 되어, 결합도가 높아질 수 있다.

toEntity 사용

  • 생성 로직에 변화가 거의 없을 때
  • 엔티티와 DTO의 결합도를 낮춰줄 수 있어 엔티티의 생성 로직이 변경되어도 DTO를 수정할 필요가 없어 엔티티와 DTO의 관심사를 분리할 수 있다.

따라서 엔티티를 생성하는 로직은 엔티티 클래스에 위치하는 것이 더 적절하다고 판단했다.

@Getter
@Setter
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class OrderRequestDto {

    @NotNull(message = "제품 아이디는 필수입니다.")
    private Long productId;

    public Orders toEntity(Member buyer, Member seller, Product product) {
        return Orders.builder()
                .orderPrice(product.getPrice())
                .orderStatus(OrderStatus.거래시작)
                .buyer(buyer)
                .seller(seller)
                .product(product)
                .build();
    }
}

▶️ 응답 DTO

응답 DTO는 서버가 클라이언트에게 보내는 데이터를 표현하는 객체이다. 따라서 엔티티의 데이터를 기반으로 생성되므로, 정적 팩토리 메소드를 응답 DTO 클래스 내부에 위치하도록하여, DTO 클래스가 데이터 표현의 책임을 가지게 된다.

이 때, 엔티티 내에 toResponse 메소드를 정의하여 직접 DTO로 변환하는 경우도 생각해보았는데, 이 경우는 엔티티와 DTO 간의 결합도가 증가하여 정적 팩토리 메소드를 사용하기로 결정했다.

@Getter
@Setter
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class BuyerPurchaseHistoryResponseDto {

    private Long orderId;
    private int orderPrice;
    private OrderStatus orderStatus;

    public static BuyerPurchaseHistoryResponseDto from(Orders orders) {
        return BuyerPurchaseHistoryResponseDto.builder()
                .orderId(orders.getId())
                .orderPrice(orders.getOrderPrice())
                .orderStatus(orders.getOrderStatus())
                .build();
    }

}

▶️ 참고

https://www.inflearn.com/questions/1238628/dto%EC%97%90%EC%84%9C-toentity-vs-entity-%EC%95%88%EC%97%90-%EC%A0%95%EC%A0%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C?commentId=332958

0개의 댓글