[Spring]Builder 패턴 vs 생성자, 무엇이 더 나을까?

2025. 4. 28. 15:11·Spring

배달 어플 프로젝트를 진행 중 데이터를 객체 타입으로 전달하기 위해 DTO(Data Transfer Object)의 생성 방식에 대해 고민이 생겼다. Java에서 DTO를 생성하는 방법엔 대표적으로 2가지 방법이 존재한다.

    1. Builder 패턴 (예: CartResponseDto.builder())
    2. 직접 생성자 호출 (예: new MenuAdminResponseDto(menu))

이 글에서는 두 접근법을 금융 IT와 보안 관점에 더 중점을 두고 어떤 게 더 적합한지 글을 작성해보려고 한다.


✅ DTO 생성 방식 

@Getter
@AllArgsConstructor
@Builder
public class MenuAdminResponseDto {
    private final Long menuId;
    private final Category category;
    private final String menuName;
    private final String content;
    private final MenuStatus menuStatus;
    private final LocalDateTime createdAt;

    public MenuAdminResponseDto(Menu menu) {
        this.menuId = menu.getId();
        this.category = menu.getCategory();
        this.menuName = menu.getName();
        this.content = menu.getContent();
        this.menuStatus = menu.getStatus();
        this.createdAt = menu.getCreatedAt();
    }
}

 

위의 코드가 있을땐 두가지의 방법으로 DTO를 생성할 수 있다.

♐ Builder 패턴

  • Builder 패턴은 Lombok 같은 라이브러리나 수동으로 구현하여 객체를 체이닝 방식으로 생성한다.
  • 예를 들어, Builder 패턴의 생성은 다음과 같다.
MenuAdminResponseDto.builder()
    .menuId(menu.getId())
    .category(menu.getCategory())
    .menuName(menu.getName())
    .content(menu.getContent())
    .menuStatus(menu.getStatus())
    .createdAt(menu.getCreatedAt())
    .build();

 

  • 이 방식은 가독성이 높고, 복잡한 DTO를 유연하게 생성할 수 있다.

 

♐ 직접 생성자 호출

  • 직접 생성자 호출은 Menu 객체를 사용자 정의 생성자에 전달하여 MenuAdminResponseDto를 생성한다:
new MenuAdminResponseDto(menu);

 

또는 @AllArgsConstructor를 사용해 모든 필드를 직접 전달할 수도 있다:

new MenuAdminResponseDto(menu.getId(), menu.getCategory(), menu.getName(), menu.getContent(), menu.getStatus(), menu.getCreatedAt());

 

  • 두 경우 모두 생성자 호출 방식으로, 간단하지만 필드가 많아지면 가독성과 유지보수성이 떨어질 수 있다.

 

✅ Builder 패턴 vs 직접 생성자 호출

  • 금융 시스템에서 DTO는 거래 내역, 결제 정보, 사용자 데이터 등 민감한 정보를 다루므로, 생성 방식의 선택은 보안과 유지보수성에 큰 영향을 미친다. MenuAdminResponseDto를 기준으로 두 방식의 장단점을 비교해보자.

1️⃣ 가독성과 유지보수성

Builder 패턴

  • MenuAdminResponseDto는 현재 6개 필드를 가지지만, 금융 시스템에서는 규제나 비즈니스 요구사항(예: auditTrail, securityToken 추가)으로 필드가 늘어날 가능성이 크다.
  • Builder 패턴은 각 필드를 명시적으로 지정하므로 가독성이 뛰어나며, 개발자의 실수를 줄인다.

직접 생성자 호출

  • new MenuAdminResponseDto(menu)는 Menu 객체의 필드 매핑을 내부적으로 처리하여 간결하다. 하지만 필드 추가 시 사용자 정의 생성자 내부 로직을 수정해야 한다.
  • 예를 들어, modifiedAt를 추가하려면 생성자를 업데이트해야 하며, 이는 기존 코드를 사용하는 모든 곳에 영향을 미칠 수 있다
💡 결론: 복잡하고 자주 변경되는 DTO를 다루는 금융 시스템에서 Builder 패턴은 가독성과 유지보수성 면에서 우수

 

📋 사례

글로벌 금융 플랫폼의 DTO 확장2021년, PayPal은 새로운 규제(예: EU의 PSD2)에 대응하기 위해 DTO에 authToken 필드를 추가했다. Builder 패턴을 사용한 덕분에 기존 코드 수정 없이 필드를 확장할 수 있었다.

 

2️⃣ 보안성과 데이터 무결성

Builder 패턴

  • Builder는 불변 객체를 생성하기 쉽다.
  • MenuAdminResponseDto는 final 필드를 사용해 불변성을 보장하며, Builder를 통해 .menuId(Objects.requireNonNull(menu.getId())) 같은 유효성 검사를 체이닝 단계에서 추가할 수 있다.
  • 예를 들어, menuId가 null이거나 잘못된 값이면 결제나 메뉴 처리에 오류가 발생할 수 있다.

직접 생성자 호출

  • MenuAdminResponseDto의 사용자 정의 생성자는 불변성을 보장하지만, 유효성 검사(예: menu.getId()가 null인지 확인)가 없다.
  • @AllArgsConstructor를 사용하면 모든 필드를 수동으로 전달해야 하므로 실수로 null 값을 넣을 위험이 있다.
결론: 보안과 데이터 무결성을 위해 Builder 패턴은 더 안전한 선택

 

3️⃣ 성능

Builder 패턴

  • MenuAdminResponseDto.builder()는 객체 생성 시 약간의 오버헤드가 있다. 하지만 금융 시스템에서 DTO 생성은 I/O 작업(예: 데이터베이스 쿼리)이나 네트워크 호출에 비해 훨씬 적은 시간을 차지하므로, 이 오버헤드는 무시할 만하다.

직접 생성자 호출

  • new MenuAdminResponseDto(menu)는 생성자 호출이 간단하므로 약간의 성능 이점이 있다.
결론: 성능 차이는 미미하며, 금융 시스템에서 보안과 유지보수성은 성능보다 우선순위가 높으므로 Builder 패턴은 적합

 

4️⃣ 확장성과 재사용성

Builder 패턴

  • MenuAdminResponseDto는 새로운 필드를 추가하거나 기존 필드를 제거할 때 유연하다.
  • 예를 들어, PSD2 규제 대응을 위해 authToken 필드를 추가하려면 .authToken(menu.getAuthToken())만 추가하면 된다.

직접 생성자 호출

  • new MenuAdminResponseDto(menu)는 새로운 필드를 추가하려면 사용자 정의 생성자를 수정하거나 새로운 생성자를 만들어야 한다.

 

✅ 결론

  • 금융 IT 시스템에서 DTO는 복잡하고, 보안 요구사항은 엄격하며, 규제 변화로 인해 자주 수정된다.
  • 따라서 가독성,보안성,유지보수성,확장성에 유리한 Builder 패턴이 적합하다.

 

 

 

 

'Spring' 카테고리의 다른 글

[Spring]N+1 문제  (1) 2025.05.08
[Spring] 트랜잭션 내부 호출 문제  (1) 2025.05.01
[Spring]오프셋 페이징보다 커서 페이징을 써야하는 이유  (1) 2025.04.25
[Spring/JPQL] JPQL이 무엇인지 알고 사용하자  (1) 2025.04.18
[Spring]Converter 보다 세부적으로 타입변경하는 법  (0) 2025.04.16
'Spring' 카테고리의 다른 글
  • [Spring]N+1 문제
  • [Spring] 트랜잭션 내부 호출 문제
  • [Spring]오프셋 페이징보다 커서 페이징을 써야하는 이유
  • [Spring/JPQL] JPQL이 무엇인지 알고 사용하자
코딩로봇
코딩로봇
금융 IT 개발자
  • 코딩로봇
    쟈니의 일지
    코딩로봇
  • 전체
    오늘
    어제
    • 분류 전체보기 (137) N
      • JavaScript (8)
      • SQL (10)
      • 코딩테스트 (30) N
        • Java (15)
        • SQL (13) N
      • Java (10)
      • 프로젝트 (22) N
        • 트러블슈팅 (7)
        • 프로젝트 회고 (13) N
      • git,Github (2)
      • TIL (36) N
      • Spring (17) N
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    java #arraylist #list #배열
    스파르타 코딩 #부트캠프 #첫ot
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코딩로봇
[Spring]Builder 패턴 vs 생성자, 무엇이 더 나을까?
상단으로

티스토리툴바