티스토리 뷰

2. 빌더(Builder)

:: Builder 패턴은 3가지로 분리되어 호출

// 1) 빌더 정의
Member.MemberBuilder builder = Member.builder()

// 2) 필드 설정
builder.name("Aaron")
       .email("aaron@example.com")
         
// 3) 객체 생성
Member aaron = builder.build();

 

- 합쳐서 사용할 경우, 아래와 같이 사용한다.

Member aaron = Member.builder()
        .email("aaron@example.com")
        .name("Aaron")
        .build();

2.1 builder의 장점

:: 생성자가 아닌 빌더를 통해 객체를 생성하는 이유

1) 원하는 필드만 설정 가능

더보기
@Builder
public class Member {
    private Integer id;
    private String name;
    private int age;
    private String email;
}

// 생성자 사용 시,
Member aaron = new Member(1, "Aaron", 10, "aaron@example.com");

// 빌더 사용 시,
Member aaron = Member.builder()
        .name("Aaron")
        .email("aaron@example.com")
        .build();

2) 생성자와 달리 필드값 주입 순서에 종속 x

더보기
Member aaron = Member.builder()
        .name("Aaron")
        .email("aaron@example.com")
        .build();
        
// ...

Member aaron = Member.builder()
        .email("aaron@example.com")
        .name("Aaron")
        .build();

3) 필드 값 주입 역할을 마음껏 분리 가능

더보기
String type = "THANKS_MESSAGE"; // "HELLO_MESSAGE"

// (1) 빌더 정의
MessageSender.MessageSenderBuilder builder = MessageSender.builder();

// (2) 필드 설정
// (2.1) 공통 부분을 먼저 설정하고
builder
        .receiver("Aaron")
        .sender("Baron")
        .type(type);

// (2.2) 다른 부분은 따로 설정한다 (조건부)
if (type.equals("THANKS_MESSAGE")) {
    builder
            .title("감사합니다")
            .message("정말 감사합니다");
}
if (type.equals("HELLO_MESSAGE")) {
    builder
            .title("안녕하세요")
            .message("정말 반갑습니다");
}

// (3) 객체 생성
MessageSender sender = builder.build();

2.2 Lombok에서의 Builder 패턴의 여러 형태

1) @Builder
:: 클래스 단위의 @Builder 선언이 아닌 생성자 단위의 @Builder 선언을 통해 필드 제약

:: 필드의 제약을 통해 생성자의 파라미터를 제한

더보기
@Builder // 클래스 단위 builder 선언
public class Member {
    private Integer id;
    private String name;
    private int age;
    private String email;
}
// ...
public class Member {
    private Integer id;
    private String name;
    private int age;
    private String email;
    
    @Builder // 빌더를 클래스가 아닌 생성자에 설정 - 제약 조건 설정에 유리
    public Member(String name, String email) {
        this.name = name;
        this.email = email;
    }
}

2) @Builder.Default

:: 필드 설정이 없을 경우 객체 생성 시 설정해줄 필드 기본값

더보기
@Builder
public class Member {
    private Integer id;
    @Builder.Default // 기본 설정값 부여 가능
    private String name = "Unnamed";
    private int age;
    @Builder.Default
    private String email = "Undefined";
}

3) @Singular

:: 컬렉션 타입 필드에 대해 단일 항목을 추가할 수 있는 메서드를 빌더 클래스에 자동으로 생성

:: Collection(Map, Set, List)에 값을 한번에 넣지않고, 하나씩 주입

더보기
@Builder
public class Member {
    private Integer id;
    private String name;
    private int age;
    private String email;
    @Singular // 해당을 통해 하나씩 배분 가능
    private List<String> favorites;
}

// 적용 X시,
Member member = Member.builder()
        .id(1)
        .name("John")
        .age(30)
        .email("john@example.com")
        .favorites(Arrays.asList("Reading", "Gaming", "Traveling")) // 한 번에 리스트로 추가
        .build();

// 적용 O시,
Member baron = Member.builder()
        .name("Baron")
        .email("baron@example.com")
        .favorite("Book") // 분할하여 추가 가능
        .favorite("Cook")
        .build();

4) @Builder 사용 시, Validation 로직을 포함한 Custom Builder 정의

더보기
@Builder
public class Member {
    private Integer id;
    private String name;
    private int age;
    private String email;

    public static class MemberBuilder { // ~Builder를 받아 제약 사항 적용
        public MemberBuilder age(int age) {
            if (age >= 30) {
                throw new RuntimeException("30세 이상은 설정 불가능합니다.");
            }
            this.age = age;
            return this;
        }
    }
}

참조

ASAC 수업자료

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함