개발을 진행하다보면 생성자를 통해 객체를 많이 만들게 된다.
객체가 가지고 있는 인자들이 많을 경우, 그 인자들이 어떠한 것인지 헷갈리는 경우가 있다.
또한 생성자 호출을 위해서 설정하고싶지 않는 매개변수의 값까지 지정해줘야 하는 불편함도 있다.
즉, 생성자를 빌더 패턴으로 생성하지 않았을 경우 코드를 읽을 때 각 값의 의미가 무엇인지 헷갈릴 수 있고, 매개변수가 몇 개 인지 항상 확인해야 하며, 실수로 매개변수의 순서가 바뀌더라도 컴파일러가 잡지 못하여 런타임 에러로 이어지게 될 수 있다.
빌더 패턴(BUilder Pattern)이란 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴이다.
생성자 인자로 너무 많은 인자가 사용되는 경우, 어떠한 인자가 어떠한 값을 나타내는지 확인하기 힘들다.
또 어떠한 인스턴스의 경우에는 특정 인자만 생성해야 하는 경우가 발생한다.
이러한 문제를 해결하기 위해서 빌더 패턴을 사용할 수 있다.
@Builder 어노테이션을 사용하면 따로 Builder Class를 만들지 않고 사용할 수 있다.
@Entity
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User {
private String username;
private int age;
private String email;
private String address;
private int zipCode;
@Builder
public User(String username, int age, String eamil, String address, int zipCode) {
this.username = username;
this.age = age;
this.email = email;
this.address = address;
this.zipCode = zipCode;
}
}
public class Main {
public static void main(String[] args) {
//빌더 패턴을 통해 어떤 필드에 어떤 값을 넣어주는지 명확히 눈으로 확인할 수 있다.
User user = User.builder("소라")
.age(30)
.email(test@gmail.com)
.address("서울특별시 강남구")
.zipCode(06325)
.build();
}
}
@Builder
Builder 패턴을 자동으로 생성해주는데, builderMethodName에 들어간 이름으로 빌더 메소드를 생성해 준다.
생성자에 @Builder 사용
클래스 레벨에서 @Builder와 @NoArgsConstructor를 함께 쓰면 오류가 발생한다.
이를 해결하기 위해서는 모든 필드를 가지는 생성자를 만들어야 하는데, @AllArgsConstructor를 사용하는 것은 위험하다.
클래스에 존재하는 모든 필드에 대한 생성자를 자동으로 생성하는데, 인스턴스 멤버의 선언 순서에 영향을 받기 때문에 변수의 순서를 바꾸면 생성자의 입력 값 순서도 바뀌게 되어 검출되지 않는 치명적인 오류를 발생시킬 수도 있다.
이를 해결하기 위해 생성자에 @Builder를
붙여주어, @AllArgsConstructor를 쓰는 일이 없도록 한다.
builder 메소드
User객체를 생성해야 하는데 address 필드와 zipCode의 필드가 필요 없는 상황이 있다고 가정을 한다면
우리는 address 필드와 zipCode에 더미 값을 넣어주거나 그 두 개의 필드를 가지고 있지 않은 생성자를 새로 만들어주어야 한다.
이러한 작업이 반복이 된다면 많은 시간을 낭비하고 코드의 양이 증가할 수 있는데, 이럴 때 빌더를 이용하면 동적으로 처리할 수 있다.
그리고 이렇게 필요한 데이터만 설정할 수 있는 빌더의 장점은 테스트용 객체를 생성할 때 용이하게 해 주고, 불필요한 코드의 양을 줄이는 등의 이점을 가질 수 있다.
새롭게 추가되는 변수 때문에 기존의 코드를 수정해야 하는 상황이 발생했을 때, 기존에 작성된 코드의 양이 방대하다면 감당하기 어려울 수도 있다.
하지만 빌더 패턴을 이용하면 새로운 변수가 추가되는 등의 상황에도 기존의 코드에 영향을 주지 않을 수 있다.
빌더 패턴을 사용하면 매개 변수가 많아져도 가독성을 높일 수 있다.
생성자로 객체를 생성하는 경우, 매개변수가 많아지면 코드의 가독성이 떨어지게 된다.
각각의 값들이 무엇을 의미하는지 바로 파악이 어렵고, 클래스 변수가 많아지면 더욱 코드를 읽기 힘들어진다.
하지만 빌더 패턴을 적용하면 가독성을 높일 수 있고, 직관적으로 어떤 데이터에 어떤 값이 설정되는지 쉽게 파악할 수 있다.
개발을 진행하면서 많은 개발자들이 흔히 수정자 패턴(Setter)을 흔히 사용한다.
굉장히 편하다는 장점이 있지만 Setter를 구현한다는 것은 불필요하게 확장 가능성을 열어두는 것이다.
이는 Open-Closed 법칙에 위배되고, 불필요한 코드 리딩 등을 유발한다.
그렇기 때문에 클래스 변수를 final로 선언하고 객체의 생성은 빌더에 맡기는 것이 좋다.