보통 객체를 정의하고 그 객체를 생성할 때 생성자를 사용 할 것이다.
Member member = new Member("han", 28, "student");
빌더 패턴으로는
Membere member = Member.builder()
.name("han")
.age(28)
.jab(student)
.build();
이것만 보면 생성자가 훨씬 간단해 보인다.
그럼에도 빌더 패턴을 사용하는 이유는 뭘까?
Builder 패턴을 적용한 예제를 보겠다.
아래는 내가 프로젝트에서 사용한 Member Entity이다.
public class Member {
@Id
@Column(name = "id", columnDefinition = "BINARY(16)")
private UUID id;
@NotNull
private String email;
@NotNull
@Column(columnDefinition = "varchar(8)")
private String nickname;
@Column(columnDefinition = "varchar(256) default 'image.jpg'")
private String profileImage;
@Column(columnDefinition = "tinyint(1) default '0'")
private boolean closetFind;
@Column(columnDefinition = "tinyint(1) default '0'")
private boolean accountFind;
}
Member 객체를 생성자를 통해 생성해보겠다.
Member member = new Member(uuid.randomuuid(), "email@ssafy.com", "image.jpg", 1, 1)
빌더 패턴을 사용하는 경우를 보자.
Member member = Member.Builder()
.id(uuid.randomuuid)
.email("email@ssafy.com")
.profileImage("image.jpg")
.closetFind(1)
.accountFind(1)
.build();
다음과 같이 직관적으로 각 필드에 어떤 데이터가 들어갔는지 확인할 수 있다.
또한 Setter를 사용하지 않았기 때문에 불변성 또한 확보할 수 있다.
추가로 순서가 바뀌어도 상관이 없다.
id 보다 먼저 email이 나와도 된다는 뜻!
Builder 패턴을 사용하려면 구현을 먼저 해야한다.
검색을 조금 해보면 알겠지만 매 프로젝트마다 이걸 직접 구현하라니?
하지만 우리에게는 사랑스러운 Lombok이 있다!
@Entity
@Getter
@NoArgsConstructor
@DynamicInsert
public class Member {
@Id
@Column(name = "id", columnDefinition = "BINARY(16)")
private UUID id;
@NotNull
private String email;
@NotNull
@Column(columnDefinition = "varchar(8)")
private String nickname;
@Column(columnDefinition = "varchar(256) default 'https://moeutto-bucket.s3.ap-northeast-2.amazonaws.com/default_image.jpeg'")
private String profileImage;
@Column(columnDefinition = "tinyint(1) default '0'")
private boolean closetFind;
@Column(columnDefinition = "tinyint(1) default '0'")
private boolean accountFind;
@Builder(toBuilder = true)
public Member(UUID id, String email, String nickname, String profileImage, boolean closetFind, boolean accountFind) {
this.id = id;
this.email = email;
this.nickname = nickname;
this.profileImage = profileImage;
this.closetFind = closetFind;
this.accountFind = accountFind;
}
}
아래처럼 만들어 주거나
@AllArgsConstructor
@Builder
클래스 위에 어노테이션을 추가해 주면 된다
@Builder(toBuilder = true)
toBuilder는 뭘까?
다음 포스팅에서 작성해보겠다.