IntelliJ Plugin을 활용한 빌더 패턴 만들기

Jeongkuk Seo
sjk5766
Published in
10 min readFeb 20, 2023

최근까지 미니 프로젝트들을 수행하면서 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의 빌더패턴을 직접 만들 것인가? 오늘까진 연습으로 그랬다 치고 이젠 절대 그러고 싶지 않다.

--

--