@Builder란?
Lombok 라이브러리에서 제공하는 어노테이션으로, 자바에서 빌더 패턴을 손쉽게 구현할 수 있도록 도와준다.
@Builder 어노테이션을 사용하면 복잡한 객체를 생성할 때 필요한 코드를 줄이고, 가독성 및 유지보수성을 향상시킬 수 있다.
@Builder 어노테이션 사용 방법을 알아보기 앞서 빌더 패턴에 대해 알아보자.
빌더 패턴
빌더 패턴은 복잡한 객체를 단계별로 구축할 수 있게 해주는 디자인 패턴이다.
이해를 돕기 위해, 일상 생활에서 익숙한 "피자 주문" 과정을 예로 들어보자.
피자 주문하기
피자를 주문할 때, 우리는 다양한 토핑을 선택할 수 있다.
예를 들어, 치즈 피자에 페퍼로니, 올리브, 버섯 등을 추가할 수 있다. 하지만 모든 사람이 같은 토핑을 원하는 것은 아니다.
어떤 사람은 올리브를 싫어할 수도 있고, 어떤 사람은 버섯만 추가하고 싶어할 수도 있다.
전통적인 방식
만약 피자 가게가 전통적인 방식으로만 피자를 제공한다면,
고객이 원하는 모든 조합의 피자를 미리 만들어놓아야 한다.
이는 매우 비효율적이며, 고객의 정확한 요구사항을 충족시키기 어렵다.
빌더 패턴 방식
이제, '빌더 패턴'을 피자 가게에 적용해보자.
고객은 기본 피자 베이스를 선택한 후, 원하는 토핑을 단계별로 추가할 수 있다.
각 단계에서 고객의 선택에 따라 피자가 점점 완성된다.
빌더 패턴을 사용하면, 고객은 자신만의 맞춤형 피자를 쉽게 주문할 수 있다.
피자 가게는 미리 모든 가능한 피자 조합을 준비할 필요가 없으며, 고객은 자신이 원하는 정확한 피자를 받을 수 있다.
빌더 패턴은 '피자 만들기'처럼, 복잡한 객체(여기서는 피자)를 단계별로 조립하는 과정을 간소화한다.
빌더 패턴 적용
빌더 패턴을 코드에 적용해보자.
1단계: 기본 클래스 설계
먼저, 생성하고자 하는 객체의 클래스를 정의한다. 예를 들어, 우리가 만들고자 하는 객체가 Book이라고 해보자. Book 클래스에는 제목(title), 저자(author), 가격(price) 등의 필드가 있을 수 있다.
public class Book {
private String title;
private String author;
private double price;
// 생성자, 게터, 세터 등 기본적인 메서드들...
}
2단계: 빌더 클래스 생성
Book 클래스 내부에 BookBuilder라는 이름의 static 내부 클래스를 생성한다. 이 클래스는 Book 객체를 단계적으로 구성하기 위한 메서드들을 제공한다.
public class Book {
private String title;
private String author;
private double price;
// Book의 내부에 Builder 클래스를 정의한다.
public static class BookBuilder {
private String title;
private String author;
private double price;
public BookBuilder title(String title) {
this.title = title;
return this;
}
public BookBuilder author(String author) {
this.author = author;
return this;
}
public BookBuilder price(double price) {
this.price = price;
return this;
}
public Book build() {
Book book = new Book();
book.title = this.title;
book.author = this.author;
book.price = this.price;
return book;
}
}
}
3단계: 빌더 패턴 사용
BookBuilder를 사용하여 Book 객체를 생성한다. 이 과정에서 필요한 속성을 메서드 체인 방식으로 호출하여 설정하고, 마지막에 .build() 메서드를 호출하여 최종적인 Book 객체를 생성한다.
public class Main {
public static void main(String[] args) {
Book book = new Book.BookBuilder() //book 객체 생성
.title("The Great Gatsby")
.author("F. Scott Fitzgerald")
.price(30.0)
.build();
System.out.println(book);
}
}
이해하기
- 메서드 체인: BookBuilder의 각 메서드는 BookBuilder 객체 자신을 반환한다. 이를 통해 .title().author().price()와 같이 연속적으로 메서드를 호출할 수 있다. 이런 방식을 메서드 체이닝이라고 한다.
- 유연성: 빌더 패턴을 사용하면, 객체를 생성할 때 필요한 속성을 유연하게 설정할 수 있다. 예를 들어, 가격을 설정하지 않고 책을 생성하는 것도 가능하다.
- 가독성: 생성자를 사용해 많은 매개변수를 전달하는 것보다 빌더 패턴을 사용하면 코드의 가독성이 크게 향상된다. 각 매개변수의 의미가 명확해지기 때문이다.
빌더 패턴은 객체 생성 과정을 더 직관적이고 유연하게 만들어 준다. 초보자도 이 패턴을 통해 복잡한 객체를 쉽게 구성하고 관리할 수 있게 된다.
@Builder 사용 방법
@Builder의 주요 특징:
- 가독성 향상: 빌더 패턴을 사용하면, 생성자에 많은 매개변수가 필요한 객체를 생성할 때, 어떤 매개변수가 어떤 값을 나타내는지 명확하게 할 수 있다. 이는 매개변수의 이름을 직접 지정하여 객체를 생성하기 때문이다.
- 유연성 증가: 필요한 속성만으로 객체를 생성할 수 있으며, 같은 객체를 다양한 상태로 쉽게 생성할 수 있다.
- 불변성(Immutable) 지원: 생성된 객체의 상태를 변경할 수 없게 만들어, 객체의 안전성을 높일 수 있다. 빌더 패턴을 사용하면, 객체 생성 후에는 해당 객체의 상태를 변경하지 않고 새로운 객체를 생성하는 방식으로 사용될 수 있다.
@Builder 사용 전 예시
public class Book {
private String title;
private String author;
private double price;
public Book(String title, String author, double price) {
this.title = title;
this.author = author;
this.price = price;
}
// 게터와 세터...
}
위 예시는 전통적인 빌더 패턴 구현 방식을 보여준다. @Builder를 사용하면 이런 내부 클래스를 만들지 않아도 Lombok이 자동으로 필요한 빌더 코드를 생성해 준다.
@Builder 사용 후 예시
import lombok.Builder;
@Builder
public class Book {
private String title;
private String author;
private double price;
// 게터와 세터...
}
@Builder 어노테이션을 클래스에 추가하기만 하면 된다. 이후 Lombok이 컴파일 시 자동으로 빌더 패턴을 구현한 코드를 생성해 준다.
사용 예시
@Builder를 사용한 클래스의 인스턴스를 생성하는 방법은 매우 간단하다. Book 클래스의 인스턴스를 만들 때, Book.builder() 메서드를 호출한 후, 체인 메서드를 사용하여 필요한 속성을 설정하고, .build()를 호출하여 객체를 생성한다.
public class Main {
public static void main(String[] args) {
Book book = Book.builder()
.title("The Great Gatsby")
.author("F. Scott Fitzgerald")
.price(30.0)
.build();
System.out.println(book.getTitle()); // "The Great Gatsby"
System.out.println(book.getAuthor()); // "F. Scott Fitzgerald"
System.out.println(book.getPrice()); // 30.0
}
}
'프로그래밍 언어 > Spring' 카테고리의 다른 글
[Spring] 좋은 객체 지향 설계의 5가지 원칙(SOLID) (1) | 2024.02.27 |
---|