Member member = new Member(1L, "chulsoo", "seoul", "...", "...", ......)
public class Member {
private Long id;
private String name;
private String address;
public void setId(Long id) {
this.id=id;
}
public void setName(String name) {
this.name=name;
}
public void setAddress(String address) {
this.address=address;
}
}
<필드 값 세팅>
Member member = new Member();
member.setId(1L);
member.setName("chulsoo");
member.setAddress("seoul");
public class Member {
private Long id;
private String name;
private String address;
public Member(Builder builder) {
this.id=builder.id;
this.name=builder.name;
this.address=builder.address;
}
public static Builder builder() {
return new Builder();
}
public static class Builder{
private Long id;
private String name;
private String address;
public Builder id(Long id) {
this.id=id;
return this;
}
public Builder name(String name) {
this.name=name;
return this;
}
public Builder address(String address) {
this.address=address;
return this;
}
public Member build() {
return new Member(this);
}
}
}
다음과 같이 세팅한 후 빌더를 사용하면
Member member = Member.builder()
.id(1L)
.name("chulsoo")
.address("seoul")
.build();
과 같이 가독성도 좋고 불변성도 챙길 수 있다.
근데 빌더도 코드가 너무 길어지면 빌더 선언 부분에서 가독성이 떨어질 수 있다. 그래서 다음과 같이 선언한다. @Builder
애노테이션을 사용하자.
public class Member {
private Long id;
private String name;
private String address;
@Builder
public Member(String name, String address) {
this.name=name;
this.address=address;
}
}
위 코드에서는 id는 builder로 만들지 않을 것이기 때문에 클래스가 아니라 생성자에서 @Builder
를 달아두었다.
다음과 같이 유효성 검사도 해줄 수 있다.
public class Member {
private Long id;
private String name;
private String address;
@Builder
public Member(String name, String address) {
Assert.hasText(name, "name은 필수");
Assert.hasText(address, "address은 필수");
this.name=name;
this.address=address;
}
}
private
으로 선언하고 정적 팩토리 메서드를 활용하는 것도 방법이 될 수 있다.public class Member {
private Long id;
private String name;
private String address;
// 생성자 내부에 유효성 검증
@Builder(access = AccessLevel.PRIVATE) // 외부에서 직접 builder 사용 못하게
private Member(String name, String address) {
Assert.hasText(name, "name은 필수");
Assert.hasText(address, "address은 필수");
this.name = name;
this.address = address;
}
// 외부에서 호출 가능한 정적 팩토리 메서드
public static Member create(String name, String address) {
return Member.builder()
.name(name)
.address(address)
.build();
}
}
Member member = Member.create("user1","서울시 용산구");
CreateMemberDTO
같은 DTO 을 사용해서 받는 것이 좋다고 생각한다. 예시에서는 빌더 패턴을 적용하기 위해 DTO 를 사용하지 않았다.예시에서는 필드값이 2개밖에 없고, 어차피 클래스 내부에서 빌더를 사용할 거면 굳이 빌더를 사용해야 되나?