본문 바로가기
디자인 패턴

[Design Pattern] 빌더 패턴

by 감자b 2025. 6. 1.

객체는 다음과 같은 방법으로 생성할 수 있다.

 

1. 생성자(Constructor)

public class User {
    private String name;
    private String email;
    private String address;
    private Integer age;

    public User() {
    }

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

    public User(String name, String email, String address, Integer age) {
        this.name = name;
        this.email = email;
        this.address = address;
        this.age = age;
    }
}
User user = new User("hbb", "hbb@example.com", null, 25);

 

해당 방법은 매개변수가 많다면 가독성이 저하되고, 실수로 같은 타입의 매개변수를 순서를 바꿔서 전달한다면 찾기 어려운 버그로 이어질 수 있다. 또한 선택적으로 매개변수 처리의 어렵기 때문에 일부 매개변수만 설정하려면 나머지 값에 null이나 기본값을 전달하거나 매개변수가 다른 생성자를 만들어야 한다는 단점이 있다.

 

 

2. Setter/Getter 메서드

해당 방법은 기본 생성자로 객체를 생성한 후, setter 메서드를 사용해 개별 필드를 설정하는 방식이다.

이는 객체의 상태가 언제든 변경될 수 있어 불변 객체를 만들 수 없고, 여러 스레드에서 동시에 setter를 호출하면 객체 상태가 일관되지 않을 수 있다는 문제가 있다.

public class User {
    private String name;
    private String email;
    private String address;
    private Integer age;

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

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

    public void setAddress(String address) {
        this.address = address;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
User user = new User();
user.setName("hbb");
user.setEmail("hbb@example.com");

 

3. 정적 팩토리 메서드

정적 팩토리 메서드에 대한 설명은 아래의 글을 참조하면 된다.

 

[Design Pattern] 정적 팩토리 메서드 패턴

정적 팩토리 메서드(Static Factory Method) 패턴은 객체 생성을 위한 디자인 패턴으로, 생성자 대신 정적 메서드를 통해 객체를 생성하는 패턴을 의미한다.public class Product { private String name; private int pr

hbb-devlog.tistory.com

 

정적 팩토리 메서드 역시 생성자와 비슷하게 다양한 매개변수 조합을 지원하려면 수많은 정적 메서드가 필요하며 가독성이 떨어지고 모든 조합의 메서드에 의미 있는 이름을 부여하기 어렵기 때문에 정적 팩토리 메서드의 장점이 사라진다.


빌더 패턴

위 문제를 해결할 수 있는 디자인 패턴으로 다음과 같은 장점이 존재한다.

  • 필요한 매개변수만 설정하는 메서드를 호출할 수 있어 매우 유연
  • 각 매개변수가 무엇인지 메서드 이름으로 명확하게 표현
  • 객체를 완전히 초기화하고 build()를 호출하므로 불변 객체 생성이 가능
  • 빌더 패턴은 메서드 체이닝을 통해 생성하므로 직관적

빌더 패턴 변환 과정

1. User 클래스 내부에 Builder 정적 클래스를 생성

2. Builder 클래스에 동일한 필드 선언

3. 필드 별로 값을 설정하는 메서드 제공

4. build() 메서드에서 User 객체 생성 및 반환

public class User {
    private String name;
    private String email;
    private String address;
    private Integer age;

    // private 생성자: Builder를 통해서만 객체 생성
    private User(Builder builder) {
        this.name = builder.name;
        this.email = builder.email;
        this.address = builder.address;
        this.age = builder.age;
    }

    // 정적 내부 클래스: Builder 정의
    public static class Builder {
        private String name;
        private String email;
        private String address;
        private Integer age;

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

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

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

        public Builder age(Integer age) {
            this.age = age;
            return this;
        }

        // User 객체를 실제로 생성하는 메서드
        public User build() {
            return new User(this);
        }
    }

    // Builder 객체 반환하는 메서드
    public static Builder builder() {
        return new Builder();
    }
}
User user = User.builder()
        .name("hbb")
        .email("hbb.example.com")
        .age(25)
        .build();