Java/문법

생성자 vs 정적 팩토리 메서드 vs 빌더 패턴

가지코딩 2025. 5. 9. 13:50

Java 에서 객체를 생성하는 방법

  • 생성자 (Constructor)
  • 정적 팩토리 메서드 (Static Factory Method)
  • 빌더 패턴 (Builder Pattern)

각각의 특징과 장단점을 살펴보자 !


1. 생성자 (Constructor)

특징:

  • 객체를 생성하는 기본적인 방식.
  • 필수 파라미터를 직접 전달하여 객체를 만든다.
  • new 키워드를 사용하여 객체를 생성한다.

장점:

  • 간단하고 직관적이다.
  • 특별한 로직 없이 기본적인 객체 생성이 필요할 때 유용하다.

단점:

  • 파라미터가 많아지면 가독성이 떨어지고, 순서에 의존하게 된다.
  • 선택적 필드를 처리하기 어려움.
public class User {
    private String name;
    private int age;

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

User user = new User("홍길동", 25);

 


2. 정적 팩토리 메서드 (Static Factory Method)

특징:

  • 객체 생성 로직을 메서드로 캡슐화하여 제공.
  • 생성자 대신 정적 메서드로 객체를 생성한다.

장점:

  • 이름으로 객체 생성 의도를 명확히 표현할 수 있다.
  • 유연성이 뛰어나며, 싱글톤 구현이나 서브클래스 반환 등의 작업이 가능하다.
  • 파라미터 순서에 의존하지 않는다.

단점:

  • 직접 객체 생성이 보이지 않아, 처음에는 익숙하지 않을 수 있다.
  • 상속이 어렵다. (생성자가 private이기 때문)
public class User {
    private String name;
    private int age;

    private User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static User createAdmin(String name) {
        return new User(name, 30);  // 기본값 30을 설정
    }
}

User admin = User.createAdmin("관리자");

3. 빌더 패턴 (Builder Pattern)

특징:

  • 객체의 생성 과정을 단계별로 나누어 처리하는 방식.
  • 생성자가 너무 복잡하거나, 많은 선택적 필드가 있을 때 유용하다.
  • 메서드 체이닝을 통해 가독성이 높다.

장점:

  • 가독성이 뛰어나며, 순서에 의존하지 않고 필드를 설정할 수 있다.
  • 객체의 불변성을 보장하면서 필드를 설정할 수 있다.
  • 선택적 필드를 설정할 때 유용하다.

단점:

  • 보일러플레이트 코드가 많고, 객체를 생성하기 위해 빌더 객체를 추가로 생성해야 한다.
  • 복잡한 객체 생성에만 유용하며, 간단한 객체에는 과할 수 있다.
public class User {
    private String name;
    private int age;

    private User(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
    }

    public static class Builder {
        private String name;
        private int age;

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

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

        public User build() {
            return new User(this);
        }
    }
}

User user = new User.Builder().setName("홍길동").setAge(25).build();
// 어노테이션 사용 시
import lombok.Builder;

public class User {
    private String name;
    private int age;

    @Builder
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

User user = User.builder()
                .name("홍길동")
                .age(25)
                .build();

 

정리

특성 생성자 정적 팩토리 메서드 빌더 패턴
용도 기본적인 객체 생성 객체 생성 로직 캡슐화, 다양한 객체 반환 복잡한 객체 생성, 선택적 필드 설정
장점 간단하고 직관적 객체 생성 의도를 명확히 표현, 유연성 높음 가독성 좋고 필드 설정 유연함
단점 파라미터가 많으면 가독성 저하 상속 불가, 직접 객체 생성이 보이지 않음 보일러플레이트 코드 많음, 복잡함
사용 시기 단순한 객체 생성 시 다양한 방식으로 객체 생성할 때 필드가 많고 선택적 설정이 필요할 때
예시 new User("홍길동", 25) User.createAdmin("홍길동") new User.Builder().setName("홍길동")
.build()