Builder란 생성자의 매개변수가 많을 때 좀 더 편리하게 객체를 만들 수 있게 도와주는 것입니다.
Builder 패턴은 점층적 생성자 패턴의 안정성과 자바빈즈 패턴의 가독성을 겸비한 패턴입니다.
클라이언트는 필요한 객체를 직접 만드는 대신에 필수 매개변수만으로 생성자 (또는 정적 팩터리)를 호출하여 Builder 객체를 얻을 수 있습니다.
이 Builder 객체가 제공하는 일종의 Setter 메서드들로 원하는 선택 매개변수를 설정합니다.
그리고 매개변수가 없는 build 메서드를 호출해 우리에게 필요한 객체를 얻어옵니다.
빌더 하나로 여러 객체를 순회하면서 만들 수 있고, 빌더에 넘기는 매개변수에 따라 다른 객체를 만들 수도 있습니다.
객체마다 부여되는 일련번호와 같은 특정 필드는 빌더가 알아서 채우게할 수 있습니다.
Builder 패턴이 어떻게 구현되어 있는지 보면 전체 생성자가 필요하다는 것을 알 수 있습니다.
@Builder, @NoArgsConstructor 어노테이션만 사용한 채로 실행하면 위와 같은 에러가 발생합니다. 왜냐하면 전체 생성자가 없기 때문입니다.
그런데 @Builder 어노테이션만 사용하면 에러가 발생하지 않습니다.
@NoArgsConstrutor 어노테이션이나 다른 생성자가 존재하지 않을 때 전체 생성자를 자동으로 만들어주기 때문입니다.
기본 생성자가 필요한 상태에서 @Builder를 사용하고 싶다면 @NoArgsConstructor, @AllArgsConstructor, @Builder 어노테이션을 함께 사용하면 에러 없이 사용할 수 있습니다.
인자가 많을 경우 쉽고 안전하게 객체를 생성할 수 있습니다.
인자의 순서와 상관없이 객체를 생성할 수 있습니다.
적절한 책임을 이름에 부여하여 가독성을 높일 수 있습니다.
public class Test {
private final String userName;
private final Long userIdx;
private final String title;
public static class Builder {
private String userName = "";
private String userIdx = "";
private String title = "";
public Builder() {}
public Builder userName(String userName){
userName = userName;
return this;
}
public Builder userIdx(Long userIdx){
userIdx = userIdx;
return this;
}
public Builder title(String title){
title = title;
return this;
}
public Test build(){
return new Test(this);
}
}
public Test(Builder builder) {
userName = builder.userName;
userIdx = builder.userIdx;
title = builder.title;
}
빌더는 생성할 클래스 안에 정적 멤버 클래스(static class Builder {…}) 로 만들어두는게 일반적입니다.
Test test = new Test
.Builder()
.userName("kimseohae")
.userIdx(1)
.title("hello")
.build();
위의 코드처럼 객체를 생성하고 호출하여 사용합니다.
@Builder(builderMethodName = "MemoBuilder")
builder 메소드명을 지정할 수 있습니다.
Builder는 원하는 요소만 꺼내다가 쓸 수 있습니다.
//from 은 메소드명
public MemberInfoResponseDto from (Member member) {
return MemberInfoResponseDto.builder()
.id(member.getId())
.name(member.getName())
.build();
}
//Service단에서 Builder 가져다 쓰기
new MemberInfoResponseDto().from(member)