Builder 패턴과 @Builder 어노테이션

프로젝트를 진행하면서 Builder 패턴의 유용함을 더욱 체감 중이다.

예를 들어 다음과 같은 클래스 Person이 있다고 하자.

public class Person {
    private String name;
    private int age;
    private String address;
    private String phoneNumber;
    private String email;
    private String job;
}

 

 

Builder 패턴을 사용하지 않았을 경우 필요에 따라 다음과 같이 수많은 생성자들이 있어야 한다.

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

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

public Person(String name, int age, String address, String phoneNumber) {
    this.name = name;
    this.age = age;
    this.address = address;
    this.phoneNumber = phoneNumber;
}

public Person(String name, int age, String address, String phoneNumber, String email) {
    this.name = name;
    this.age = age;
    this.address = address;
    this.phoneNumber = phoneNumber;
    this.email = email;
}

public Person(String name, int age, String address, String phoneNumber, String email, String job) {
    this.name = name;
    this.age = age;
    this.address = address;
    this.phoneNumber = phoneNumber;
    this.email = email;
    this.job = job;
}

// .......으아악

그 외에도 다음과 같은 불편함 점들이 있다.

  • 생성자 호출 시 인자의 순서를 고려해야 한다는 점도 불편한 점들 중 하나이다.
  • Person 클래스에 새로운 필드를 추가하고 싶을 때 그에 해당하는 생성자의 인자도 추가되어야 한다. 그렇게 되면 위의 예시처럼 생성자가 많아지게 됨은 물론 유지보수 측면에서 불편한 점이 너무 많다.
  • 또한, 생성자에 너무 많은 인자가 있는 경우 인자가 어떤 의미를 갖는지 파악하기 힘들다는 단점이 있다.

 

 


 

Builder 클래스

이럴 때 Builder 패턴을 사용하면 객체 생성 과정을 단순화 할 수 있다.

다음은 User 클래스를 위한 Builder 클래스의 예시이다.

public class User {
    private final String name;
    private final int age;
	//.......생략

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

	// ----- Builder 클래스 -----
    public static class Builder {
        private String name;
        private int age;

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

        public Builder age(int age) {
            this.age = age;
            return this;
        }
		//.......생략

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

    public String getName() {
        return this.name;
    }

    public int getAge() {
        return this.age;
    }
}

Builder 클래스는 User 클래스를 생성하는데 필요한 각각의 필드를 지정할 수 있도록 메서드를 제공해주는 클래스이다.

private User(Builder builder){
//.......
}

User 클래스의 생성자는 private 으로 선언되어 있으므로 User.Builder 클래스에서만 User 객체를 생성할 수 있다.

즉, build() 메서드를 사용하면 User 객체를 생성하고 반환할 수 있다.

 

 


 

 

@Builder 어노테이션

특히 Spring 프로젝트를 진행하면서 Lombok 라이브러리에서 제공하는 @Builder 어노테이션을 사용하면 다음과 같이 Builder 패턴을 더욱 쉽게 구현할 수 있다.

@Builder
public class User {
//.......
}
User user = User.builder()
                .name("John Doe")
                .age(30)
		//.....
                .build();

@Builder 어노테이션을 사용하면 Builder 클래스를 직접 작성하지 않아도 되어서 코드를 간결하게 작성할 수 있다.

만약 필드에 변경이 생겨나도 Builder 클래스를 수정하지 않아도 되므로 유지보수성이 높아진다는 장점이 있다.

'Java > 문법, 자료구조, 알고리즘' 카테고리의 다른 글

@Builder.Default  (0) 2023.04.16
BufferedReader로 입력 받을 때 NPE 방지하기  (0) 2023.04.04
Tree, BinaryTree  (0) 2023.04.02
PriorityQueue  (0) 2023.04.01
== 와 .equals() 차이  (0) 2023.03.28