자바에서 객체를 생성할 때 `new` 키워드를 사용한 생성자 호출 외에도 빌더 패턴을 활용하면 더 가독성 있고 유연한 코드를 작성할 수 있습니다. 특히, 필드가 많은 객체나 옵션이 다양한 경우 빌더 패턴은 매우 유용합니다.
이번 글에서는 빌더 메서드의 기본 개념, 장점, 실무 활용법을 정리하겠습니다! 👩🏻💻
빌더 패턴이란?
빌더 패턴은 복잡한 객체의 생성 과정을 단순화하고, 가독성과 유지보수성을 높이기 위해 고안된 디자인 패턴입니다.
기본 빌더 패턴 코드 예제
public class User {
private final String name;
private final int age;
private final String email;
// Builder 클래스
public static class Builder {
private String name;
private int age;
private String email;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder email(String email) {
this.email = email;
return this;
}
public User build() {
return new User(this);
}
}
private User(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.email = builder.email;
}
}
객체 생성 예제
User user = new User.Builder()
.name("rosy")
.age(20)
.email("rosy@example.com")
.build();
빌더 패턴의 장점
- 가독성
- 빌더 메서드 이름으로 각 필드가 어떤 값인지 명확히 알 수 있습니다.
- 메서드 체이닝으로 코드를 깔끔하게 작성할 수 있습니다.
- 유연성
- 필수 값과 선택 값의 조합을 쉽게 처리할 수 있습니다.
- 불변 객체를 생성할 수 있어 동시성 문제가 줄어듭니다.
- 가독성 높은 생성자 대체
- 필드가 많은 생성자는 호출 시 인자의 의미를 혼동할 수 있지만, 빌더는 이를 명확히 합니다.
Lombok으로 빌더 패턴 간단히 구현하기
Lombok은 빌더 패턴을 손쉽게 구현할 수 있는 @Builder 어노테이션을 제공합니다.
Lombok @Builder 예제
import lombok.Builder;
import lombok.ToString;
@Builder
@ToString
public class User {
private String name;
private int age;
private String email;
}
객체 생성 예제
User user = User.builder()
.name("rosy")
.age(20)
.email("rosy@example.com")
.build();
System.out.println(user); // User(name=rosy, age=20, email=rosy@example.com)
장점
- 코드 양이 크게 줄어들고 유지보수가 편리합니다.
주의점
- 필수 필드를 명확히 하고 싶다면, @Builder.Default 또는 @SuperBuilder와 함께 사용을 고려해야 합니다.
실무에서의 빌더 패턴 활용 팁
- 필수 필드 처리
- Lombok @Builder는 필수 필드에 대해 별도 검증 로직이 필요합니다. 이를 위해 @NonNull 또는 별도 생성 메서드를 추가하세요.
- 상속 구조에서의 빌더
- 상속된 클래스에서도 빌더를 사용하려면 Lombok의 @SuperBuilder를 활용하세요.
@SuperBuilder 예제
import lombok.Getter;
import lombok.experimental.SuperBuilder;
@Getter
@SuperBuilder
public class Parent {
private String parentField;
}
@Getter
@SuperBuilder
public class Child extends Parent {
private String childField;
}
사용 예제
Child child = Child.builder()
.parentField("Parent")
.childField("Child")
.build();
- DTO 변환 시 빌더 활용
- 서비스 계층에서 DTO 생성 시 빌더를 활용하면 읽기 좋은 코드를 작성할 수 있습니다.
UserDto userDto = UserDto.builder()
.id(user.getId())
.name(user.getName())
.build();
💡 빌더 패턴은 복잡한 객체 생성을 단순화하며, 특히 코드의 가독성과 유지보수성을 크게 향상시킵니다.
Lombok을 활용하면 더 쉽고 빠르게 빌더를 구현할 수 있으니 실무에서 적극적으로 활용해 보세요!
'Backend > Java' 카테고리의 다른 글
| [Java] JPA에서 발생하는 N+1 이슈: 원인부터 해결까지 (1) | 2024.11.27 |
|---|---|
| Java의 Reflection 사용법과 주의점 (0) | 2024.11.24 |
| JPA FetchType.EAGER와 LAZY의 차이 알아보기 (0) | 2024.11.22 |
| [Java]자바 메모리 관리: 스택(Stack)& 힙(Heap) (1) | 2024.11.20 |
| [Java] Optional 한눈에 정리하기 (0) | 2024.11.19 |