JAVA

[JAVA] Builder 패턴

집한구석 2021. 5. 16. 16:10
728x90

실무에서 Lombok에서 @Builder 어노테이션으로 많이 사용하나, 정확한 개념을 알기위해 기록


정의

  • 복잡한 객체를 생성하는 방법을 정의하는 클래스와 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공하는 패턴

빌더 패턴 사용해야할 경우 

  • 생성자에 인자가 많을 경우 
  • 생성자에 매개변수가 많은 경우 

일반적으로 Model로 사용하는 클래스에서는 흔히 사용하는게 자바빈 패턴 혹은 점층적 생성자 패턴을 사용하나 이러한 경우, 가독성이 좋지 않아 실수하는 경우가 생길 수가 있음, 특히 자바빈패턴 같은경우 setter사용으로 인해 불변객체로 만들 수가 없음 (아래 예시 참조) 

점층적 생성자 패턴

/* 점층적 생성자 패턴 */
public class User {

  private Long id;
  private String name;
  private String email;
  private String password;

  public User(String name, String email, String password) {
    this.name = name;
    this.email = email;
    this.password = password;
  }
}

public class Main {

  public static void main(String[] args) {
    /* 인수가 연속으로 String으로 있어서 실수 할 수가 있음 */
    User user = new User("TOM", "tgyun615@test.com", "tgyun615");
  }
}

자바빈 패턴

public class User {

  private Long id;
  private String name;
  private String email;
  private String password;

  public User() {
  }

  public void setName(String name) {
    this.name = name;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  @Override
  public String toString() {
    return "User{" +
        "name='" + name + '\'' +
        ", email='" + email + '\'' +
        ", password='" + password + '\'' +
        '}';
  }
}

public class Main {

  public static void main(String[] args) {
    User user = new User();
    user.setEmail("tgyun615@test.com");
    user.setName("김태균");
    user.setPassword("tgyun615");

    System.out.println(user.toString());

    /* 불변객체로 사용 불가, 변경됨 */
    user.setName("Tom");
    System.out.println(user.toString());
  }
}

이러한 부분을 해결해줄 수 있는 것이 빌더패턴이며, 빌더패턴은 장점이 추가적으로 존재함


빌더패턴 장점

  • 각 인자의 구성을 파악하기가 쉬움
  • 불변객체 구성이 가능함 
  • 한번 생성한 객체의 일관성이 깨지지 않음
  • 잘못된 값이 입력되었는지 검증이 가능

빌더패턴 예시

public class User {

  private Long id;
  private String name;
  private String email;
  private String password;

  public User(String name, String email, String password) {
    this.name = name;
    this.email = email;
    this.password = password;
  }

  @Override
  public String toString() {
    return "User{" +
        "name='" + name + '\'' +
        ", email='" + email + '\'' +
        ", password='" + password + '\'' +
        '}';
  }

  public static class Builder {

    private String name;
    private String email;
    private String password;

    public Builder() {
    }

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

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

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

    public User build() {
      return new User(name, email, password);
    }
  }
}

public class Main {

  public static void main(String[] args) {
    User user = new User.Builder()
        .email("tgyun615@test.com")
        .name("TOM")
        .password("tgyun615")
        .build();

    System.out.println(user.toString());
  }
}

'JAVA' 카테고리의 다른 글

[JAVA] GC의 종류  (0) 2021.05.23
[JAVA] 상태패턴  (0) 2021.05.21
[JAVA] 상속 / 컴포지션  (0) 2021.05.15
[JAVA] static 정리  (0) 2021.05.15
[JAVA] 초기화 순서  (0) 2021.05.12