@Builder는 Lombok 라이브러리에서 제공하는 어노테이션으로, 빌더 패턴(Builder Pattern)을 쉽게 구현할 수 있도록 도와줍니다. 빌더 패턴은 복잡한 객체를 생성할 때 유연하고 가독성 좋은 방식으로 객체를 생성할 수 있게 해줍니다. @Builder는 주로 객체 생성 시 필드가 많거나 선택적으로 값을 설정해야 할 때 유용합니다.
@Builder는 다음과 같은 역할을 수행합니다:
빌더 패턴을 자동으로 생성하여, 객체의 필드를 자유롭게 설정하고 객체를 생성할 수 있게 합니다.
가독성을 높여, 필드가 많은 객체를 생성할 때 생성자나 setter를 사용하지 않고, 명시적인 방식으로 객체를 구성할 수 있습니다.
불변 객체(Immutable Object)나 값 객체(Value Object)를 생성하는 데도 유용합니다. 객체를 생성한 후 값이 변경되지 않도록 설계할 수 있습니다.
가독성: 각 필드를 명시적으로 설정할 수 있어, 코드의 가독성이 향상됩니다.
선택적 필드 설정: 필요 없는 필드는 설정하지 않고, 필요한 필드만 설정하여 객체를 생성할 수 있습니다.
유연한 객체 생성: 다양한 방법으로 객체를 유연하게 생성할 수 있습니다.
불변성: 생성 후 변경되지 않는 객체를 쉽게 만들 수 있습니다.
간단한 예시
import lombok.Builder;
import lombok.ToString;
@Builder
@ToString
public class User {
private String name;
private int age;
private String email;
}
// 사용법
public class Main {
public static void main(String[] args) {
// User 객체를 빌더 패턴으로 생성
User user = User.builder()
.name("John Doe")
.age(30)
.email("john@example.com")
.build();
System.out.println(user);
}
}
위 코드에서는 @Builder를 사용하여 User 객체를 생성할 때 빌더 패턴을 적용했습니다. 필드가 많거나 일부 필드만 설정하고 싶은 경우, 빌더 패턴은 유용하게 사용할 수 있습니다.
@Builder로 생성된 빌더 메서드
@Builder는 클래스 내에 빌더 클래스와 메서드를 자동으로 생성해줍니다. 위 예시에서 User.builder()는 UserBuilder라는 클래스를 생성하고, name(), age(), email() 같은 메서드로 각 필드를 설정할 수 있게 합니다. build() 메서드를 호출하면 설정된 값들로 User 객체가 생성됩니다.
User user = new User("John Doe", 30, "john@example.com"); // 가독성 떨어짐
대신 빌더 패턴을 사용하면:
User user = User.builder()
.name("John Doe")
.age(30)
.email("john@example.com")
.build(); // 가독성 향상
불변 객체 생성:
@Builder
public class ImmutableUser {
private final String name;
private final int age;
private final String email;
}
선택적 필드:
@Getter / @Setter: 빌더로 생성된 객체의 필드에 접근할 수 있게 합니다.
@ToString: 객체를 문자열로 표현할 때 사용합니다.
@AllArgsConstructor, @NoArgsConstructor: 생성자와 함께 사용할 수 있습니다.
빌더 패턴은 복잡한 객체를 구성할 때 특히 유용합니다. 예를 들어, 객체 내에 리스트나 중첩된 객체가 있는 경우에도 쉽게 객체를 생성할 수 있습니다.
import lombok.Builder;
import lombok.ToString;
import java.util.List;
@Builder
@ToString
public class Order {
private String orderId;
private List<String> itemList;
private double totalAmount;
}
// 사용법
public class Main {
public static void main(String[] args) {
Order order = Order.builder()
.orderId("ORD12345")
.itemList(List.of("item1", "item2", "item3"))
.totalAmount(150.75)
.build();
System.out.println(order);
}
}
필드 초기화: 특정 필드를 빌더 패턴에서 기본 값으로 설정할 수 있습니다.
다중 생성 패턴: @Builder를 생성자와 함께 사용하여 객체 생성 방법을 다변화할 수 있습니다.
@Builder
public class Person {
private final String firstName;
private final String lastName;
private final int age;
@Builder.Default
private final String country = "Unknown"; // 기본값 설정
}
@Builder는 상속 관계에서 사용할 때 다소 주의가 필요합니다. Lombok은 상속받은 필드에 대해 빌더를 자동으로 생성하지 않기 때문에, 상속 관계에서 빌더 패턴을 사용하려면 하위 클래스에서 빌더를 다시 정의하거나, @SuperBuilder를 사용할 수 있습니다.
import lombok.experimental.SuperBuilder;
@SuperBuilder
public class Parent {
private String parentField;
}
@SuperBuilder
public class Child extends Parent {
private String childField;
}
결론
@Builder는 복잡한 객체를 쉽게 생성하고, 선택적으로 필드를 설정할 수 있게 해주는 강력한 도구입니다. 특히 가독성, 유연성, 불변성을 강조하는 상황에서 빌더 패턴을 적용하면 코드 유지보수가 쉬워지고, 객체 생성 로직이 간결해집니다. @Builder를 사용하면 빌더 패턴을 수동으로 구현할 필요 없이 Lombok이 이를 자동으로 처리해주므로, 더 적은 코드로 동일한 기능을 구현할 수 있습니다.