IntelliJ Plugin을 활용한 빌더 패턴 만들기
최근까지 미니 프로젝트들을 수행하면서 Entity와 Dto에 빌더 패턴이 필요하면 직접 타이핑을 했다. 지겨운 작업이라 앞으로 lombok을 써야지 생각하고 만들어 둔 미니 프로젝트에 lombok 적용 중 불현듯 번개가 머리를 스쳤다.
혹시 인텔리제이에서 제공하고 있는데 나만 모르는 게 아닐까?
찾아보니 아… plugin이 있었구나.
설치 및 사용방법에 대해 간략히 정리해보겠다.
[File] — [Settings]-[Plugins]로 들어가 Builder Generator를 찾아 설치하자.
설치가 완료된 후 내가 타이핑해서 만들어 둔 Builder 패턴을 적용한 코드와 사용한 곳의 코드를 보자. 아래 코드는 User를 생성할 때의 Request Dto다.
public class UserRequest {
private String name;
@NotBlank
private String nickname;
@Email
private String email;
@NotBlank
private String password;
@NotBlank
private String phone;
private String role;
@NotNull
private Boolean allowMarketing;
private UserRequest() {}
public UserRequest(Builder builder) {
this.name = builder.name;
this.nickname = builder.nickname;
this.email = builder.email;
this.password = builder.password;
this.phone = builder.phone;
this.role = builder.role;
this.allowMarketing = builder.allowMarketing;
}
public String getName() {
return name;
}
public String getNickname() {
return nickname;
}
public String getEmail() {
return email;
}
public String getPassword() {
return password;
}
public String getPhone() {
return phone;
}
public String getRole() {
return role;
}
public boolean getAllowMarketing() {
return allowMarketing;
}
public static class Builder {
private String name;
private String nickname;
private String email;
private String password;
private String phone;
private String role;
private Boolean allowMarketing;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder nickname(String nickname) {
this.nickname = nickname;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder password(String password) {
this.password = password;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Builder role(String role) {
this.role = role;
return this;
}
public Builder allowMarketing(Boolean allowMarketing) {
this.allowMarketing = allowMarketing;
return this;
}
public UserRequest build() {
return new UserRequest(this);
}
}
}
이 UserRequest의 Builder를 사용하는 코드는 아래와 같은 형식이다.
public static UserRequest createUserRequest(String nickname) {
return new UserRequest.Builder()
.name("서정국")
.nickname(nickname)
.email("test@gamil.com")
.password(COMMON_PASSWORD)
.phone(COMMON_PHONE)
.role(UserRole.ROLE_USER.name())
.allowMarketing(true)
.build();
}
이제 위의 코드는 지워버리고 설치한 Plugin으로 Builder 패턴을 생성해 보겠다. Mac 기준으로 command + n
윈도우 기준으로 Alt + insert
버튼을 누르면 기존에 없던 Builder
를 볼 수 있다.
버튼을 누르면 아래와 같은 Modal이 뜬다. 여기서부턴 개인의 선택인데 내 경우 새로운 파일이 아닌 Inner class로 만들고 싶었고 with와 같은 prefix를 사용하고 싶지 않았다.
그래서 위 모달에서 아래와 같이 수정을 한다.
위에서 빨간색으로 표시한 곳이 내가 수정한 곳이다. 이 설정으로 OK를 누르면 Builder 패턴에 적용할 컬럼들을 선택해야 한다. 나는 전체를 선택해서 OK 버튼을 눌렀고 생성된 코드는 아래와 같다.
public class UserRequest {
// 기존의 필드와 getter 있음
.
.
// 아래가 생성된 코드
public static final class Builder {
private String name;
private @NotBlank String nickname;
private @Email String email;
private @NotBlank String password;
private @NotBlank String phone;
private String role;
private @NotNull Boolean allowMarketing;
private Builder() {
}
public static Builder anUserRequest() {
return new Builder();
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder nickname(String nickname) {
this.nickname = nickname;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder password(String password) {
this.password = password;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Builder role(String role) {
this.role = role;
return this;
}
public Builder allowMarketing(Boolean allowMarketing) {
this.allowMarketing = allowMarketing;
return this;
}
public UserRequest build() {
UserRequest userRequest = new UserRequest();
userRequest.role = this.role;
userRequest.phone = this.phone;
userRequest.nickname = this.nickname;
userRequest.name = this.name;
userRequest.email = this.email;
userRequest.allowMarketing = this.allowMarketing;
userRequest.password = this.password;
return userRequest;
}
}
}
위 빌더 패턴이 아닌 내가 직접 타이핑한 빌더 패턴을 사용하는 코드는 아래와 같았다.
public static UserRequest createUserRequest(String nickname) {
return new UserRequest.Builder()
.name("서정국")
.nickname(nickname)
.email("test@gamil.com")
.password(COMMON_PASSWORD)
.phone(COMMON_PHONE)
.role(UserRole.ROLE_USER.name())
.allowMarketing(true)
.build();
}
위 방법 그대로 사용하려면 Plugin을 통해 자동으로 만들어진 빌더 패턴에서 private 생성자를 제거하면 된다.
// 아래가 생성된 코드
public static final class Builder {
private String name;
private @NotBlank String nickname;
private @Email String email;
private @NotBlank String password;
private @NotBlank String phone;
private String role;
private @NotNull Boolean allowMarketing;
private Builder() { <--- 외부에서 생성할 수 없으니 제거
}
public static Builder anUserRequest() {
return new Builder();
}
.
.
.
}
빌더 패턴을 나와 똑같이 사용하는 사람도 조금 다르게 사용하는 사람도 있겠지만 여기까지 코드를 작성했다면 입맛에 맞게 수정해서 사용하면 될 거 같다.
lombok을 쓰지 않는다면 빌더 패턴을 만들 때 무조건 이 plugin을 활용할 것 같다. 필드 20개가 있는 request dto나 entity의 빌더패턴을 직접 만들 것인가? 오늘까진 연습으로 그랬다 치고 이젠 절대 그러고 싶지 않다.