728x90

빌더 패턴은 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인 패턴입니다.

 

만들어봅니다!

 

Entity 역할을 하는 Person의 DTO를 Builder로 변환해 봅시다!

@Getter
@AllArgsConstructor
public class Person {
  private String name;
  private LocalDate birthday;
  private Address address;
}

 

Person을 Famil, Friend, Coworker 등으로 확장하면서 구현해보기 위해 Interface를 만들어봅니다.

public interface PersonDTO {
  String getName();
  LocalDate getBirthday();
  Address getAddress();
}

 

PersonDTO를 구현한 FriendDTO는 아래와 같습니다.

nickname 필드를 추가했습니다.

@Getter
@AllArgsConstructor
@ToString
public class FriendDTO implements PersonDTO {
  private String name;
  private String nickname;
  private LocalDate birthday;
  private Address address;
}

 

빌더 패턴을 사용하면, 매개변수가 많을 경우, 매개변수의 조합이 많을 경우 간편하게 불변 객체를 만들 수 있습니다.

 

빌더 클래스도 DTO 클래스와 동일하게 interface를 만들고 구현 객체를 만듭니다.

🙅‍♂️ 아래 코드는 나중에 수정이 될 것입니다^^,,,

public interface PersonDTOBuilder {
  PersonDTOBuilder name(String name);
  PersonDTOBuilder birthday(LocalDate birthday);
  PersonDTOBuilder address(Address address);

  PersonDTO build();
}

 

public class FriendDTOBuilder implements PersonDTOBuilder {
  private String name;
  private String nickname;
  private LocalDate birthday;
  private Address address;

  @Override
  public FriendDTOBuilder name(String name) {
    this.name = name;
    return this;
  }

  public FriendDTOBuilder nickname(String nickname) {
    this.nickname = nickname;
    return this;
  }

  @Override
  public FriendDTOBuilder birthday(LocalDate birthday) {
    this.birthday = birthday;
    return this;
  }

  @Override
  public FriendDTOBuilder address(Address address) {
    this.address = address;
    return this;
  }

  @Override
  public PersonDTO build() {
    return new FriendDTO(name, nickname, birthday, address);
  }
}

 

이렇게 작성하면 Builder 패턴으로 객체를 만들 수 있으나..

모든 새로운 빌더마다 반환 타입을 다시 지정해줘야 하는 번거로움이 생기고, 반환 타입을 실수할 가능성이 높아집니다..

 

제네릭을 사용해서 조금 더 안전한 코드를 만들어봅시다.

public interface PersonDTOBuilder<T extends PersonDTOBuilder<T>> {
  T name(String name);
  T birthday(LocalDate birthday);
  T address(Address address);

  PersonDTO build();
  PersonDTO getPersonDTO();
}

 

 

여기서 그치지 않고, Builder를 품은 DTO도 만들 수 있습니다,,🤗

@Getter
@Setter
@ToString
@AllArgsConstructor
public class CafeDTO {
  private String name;
  private String address;
  private String signature;
  private String rating;

  public static Builder builder() {
    return new Builder();
  }

  public static class Builder {
    private String name;
    private String address;
    private String signature;
    private String rating;

    private CafeDTO cafeDTO;

    public Builder name(String name) {
      this.name = name;
      return this;
    }

    public Builder address(Address address) {
      this.address = "(" + address.getZipCode() + ") " + address.getCity() + " " + address.getState();
      return this;
    }

    public Builder signature(String signature) {
      this.signature = signature;
      return this;
    }

    public Builder rating(int rating) {
      this.rating = "★".repeat(rating);
      return this;
    }

    public CafeDTO build() {
      this.cafeDTO = new CafeDTO(name, address, signature, rating);
      return this.cafeDTO;
    }

    public CafeDTO getCafeDTO() {
      return this.cafeDTO;
    }
  }
}

 

이제야 자주보던 @Builder를 선언했을 때와 같은 모양으로 쓸 수 있습니다,,

CafeDTO cafe = CafeDTO.builder()
                      .name("starbucks")
                      .address(address)
                      .signature("americano")
                      .rating(5)
                      .build();

 

여기에 마지막으로 Entity를 DTO로 바꿔주는 static 메서드도 추가가 가능하죠,,

public static CafeDTO toDTO(Cafe cafe) {
    return CafeDTO.builder()
                  .name(cafe.getName())
                  .address(cafe.getAddress())
                  .signature(cafe.getSignature())
                  .rating(cafe.getRating())
                  .build();
}

 

Entity를 DTO로,,

Cafe cafe = new Cafe("two-some", new Address("12345", "seoul", "bangbae"), "milktea", 5);
CafeDTO cafeDTOFromEntity = CafeDTO.toDTO(cafe);

 

 

 

📑

참고 자료

Chat GPT

https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EB%B9%8C%EB%8D%94Builder-%ED%8C%A8%ED%84%B4-%EB%81%9D%ED%8C%90%EC%99%95-%EC%A0%95%EB%A6%AC

 

💠 빌더(Builder) 패턴 - 완벽 마스터하기

Builder Pattern 빌더 패턴(Builder Pattern)은 복잡한 객체의 생성 과정과 표현 방법을 분리하여 다양한 구성의 인스턴스를 만드는 생성 패턴이다. 생성자에 들어갈 매개 변수를 메서드로 하나하나 받아

inpa.tistory.com

https://refactoring.guru/ko/design-patterns/builder

 

빌더 패턴

/ 디자인 패턴들 / 생성 패턴 빌더 패턴 다음 이름으로도 불립니다: Builder 의도 빌더는 복잡한 객체들을 단계별로 생성할 수 있도록 하는 생성 디자인 패턴입니다. 이 패턴을 사용하면 같은 제작

refactoring.guru

https://www.udemy.com/course/design-patterns-in-java-concepts-hands-on-projects/?couponCode=PLOYALTY0923

 

 

 

728x90