lombok 라이브러리는 반복되는 패턴을 줄여주어 코드의 간결성과 유지보수성을 크게 높여줍니다.
lombok은 Builder 패턴을 편리하게 사용할 수 있도록 @Builder 애노테이션을 제공해줍니다.
애노테이션 중에는 @Builder 외에도 @SuperBuilder 애노테이션이 존재합니다.그렇다면 @SuperBuilder는 무엇일까요?
@Builder 애노테이션과 @SuperBuilder 애노테이션의 차이에 대해 알아보려 합니다.
@Builder
@Builder는 lombok에서 제공하는 기본적인 빌터 패턴 구현 애노테이션입니다. 특정 클래스에 대해 빌더 클래스를 생성하여, 객체를 유연하게 생성할 수 있도록 도와줍니다.
주요 특징
- 단일 클래스에서 사용
- @Builder는 상속 관계가 없는 단일 클래스 객체를 생성할 때 유용
- 빌더 메서드 자동 생성
- 각각의 필드에 대한 생성 메서드 생성
- 편리한 객체 생성
- 필요한 필드만 선택적으로 초기화 가능
@Builder
public class User {
private String name;
private int age;
private String email;
}
public class Main {
public static void main(String[] args) {
User user = User.builder()
.name("koo")
.email("koosco136@naver.com")
.build();
System.out.println(user);
}
}
이처럼 @Builder 애노테이션을 사용하면 별도의 구현 없이도 Builder 패턴을 바로 사용할 수 있게 됩니다.
직접 구현한 Builder 패턴
public class User {
private String name;
private int age;
private String email;
public static Builder builder() {
return new Builder();
}
public static class Builder {
private User user;
public Builder() {
user = new User();
}
public Builder name(String name) {
this.user.name = name;
return this;
}
public Builder age(int age) {
this.user.age = age;
return this;
}
public Builder email(String email) {
this.user.email = email;
return this;
}
public User build() {
User newUser = user;
user = new User();
return newUser;
}
}
}
직접 작성하게 되면 필드값이 수정될 때마다 빌더 클래스의 메서드도 수정을 해주어야 하고, 비즈니스 로직까지 포함되버리면 가독성이 떨어지는 문제가 생깁니다. 또, 클래스마다 반복해서 코드를 작성해야 하는 문제가 생깁니다.
다시 @Builder 애노테이션을 사용한 코드를 확인해봅시다.
@Builder
public class User {
private String name;
private int age;
private String email;
}
이처럼 @Builder 애노테이션 하나만으로도 코드의 가독성을 크게 향상시킬 수 있습니다.
그러면 @SuperBuilder는 왜 필요한데?
@Builder 애노테이션은 상속 관계를 가질 때 부모 클래스의 필드와 자식 클래스의 필드를 함께 처리하기가 어렵습니다.
@Builder
public class Parent {
private String parentName;
private int parentAge;
}
@Builder
public class Child extends Parent {
private String childName;
private int childAge;
}
위와 같이 부모와 자식 모두에게 @Builder 애노테이션을 사용해도 자식 인스턴스를 만들면서 상속받은 부모 클래스의 필드값은 Builder 패턴을 이용해 초기화를 할 수 없습니다.
public class Main {
public static void main(String[] args) {
Child child = Child.builder()
.childName("child")
.childAge(20)
.build(); // 부모 속성은 초기화할 수 없음..
}
}
@SuperBuilder는 부모 속성을 쉽게 초기화하도록 도와줍니다.
@SuperBuilder
public class Parent {
private String parentName;
private int parentAge;
}
@SuperBuilder
public class Child extends Parent {
private String childName;
private int childAge;
}
이렇게 부모 클래스와 자식 클래스에게 @SuperBuilder 애노테이션을 사용하면 빌터 패턴을 이용해 자식 인스턴스를 만들 때 부모 속성까지 초기화할 수 있게 됩니다.
public class Main {
public static void main(String[] args) {
Child child = Child.builder()
.childName("child")
.childAge(20)
.parentAge(40)
.parentName("parent")
.build();
}
}
lombok 라이브러리의 @Builder와 @SuperBuilder에 대해 알아보았습니다.
사실 저는 빌더 패턴보다는 팩토리 메서드 패턴을 더 선호하는 편입니다. 빌더 패턴을 사용하게 되면 의도치 않게 속성값을 초기화하지 못할 수 있고, 인스턴스를 생성할 때 의도를 나타내지 못하는 점이 아쉬운 것 같습니다.
팩토리 메서드 패턴을 이용하면 용도에 따라 메서드 명을 구분해서 사용할 수 있고, 속성값을 초기화하지 않는 휴먼 에러를 방지할 수 있어 좋은 것 같습니다.
하지만 오히려 용도에 따라 각각의 메서드로 나누는 것은 코드 라인수가 늘어나는 단점이 될 수도 있고, 별도의 팩토리 객체를 필요로 할 수 도 있습니다. 반면, lombok이 제공하는 애노테이션을 사용하면 코드 라인수를 줄이고 빠르게 개발할 수 있다는 점은 장점인 것 같습니다.
'language > java' 카테고리의 다른 글
java의 불변 리스트 (Arrays.asList vs. List.of) (0) | 2025.01.23 |
---|---|
Java Map의 동시성 문제 (HashMap vs. ConcurrentHashMap vs. Hashtable) (0) | 2025.01.18 |