웹풀스택 공부 중
14 - 5. Java - Builder & 정적 팩토리 메서드 본문
생성자에 매개변수가 많다면 빌더를 사용하는건 어떠한가?
Builder
객체 생성의 모든 경우의 수를 지원한다
매개변수가 많은 상황에서 생성자 혹은 정적 팩토리 메소드보다 더 유용하게 사용할 수 있다
- 생성자가 넘겨줄 값을 지연시킬 수 있다
- 한번에 값을 넘겨줄 필요 없이, 계속해서 넘긴 후, 설정이 끝났을 떄 생성이 가능하다
- 순서대로 마음껏 값을 넣을 수 있다!
- 생성자가 넘겨줄 값을 지연시킬 수 있다
Builder 패턴은 3가지로 분리되어 호출된다
빌더 정의 → 필드 설정 → 객체 생성
빌더 정의
Member.MebmerBuilder builder = Member.builder()
필드 설정
builder.name("Luke").email("Luke@example.com")
객체 생성
Member luke = builder.build();
흔히 보이는 Builder 패턴은 아래와 같다. 모든 스텝이 합쳐진 상태
Member luke = Member.builder(); .email("Luke@exampe.com") .name("Luke") .build();
Builder의 장점
내가 원하는 필드만 설정할 수 있다
생성자와 달리 필드값 주입 순서에 구애받지 않는다
필드값 주입 역할을 마음껏 분리할 수 있다
원하는 시점과 상황에 필드 설정이 가능하다
예시 - 다른 부분을 따로 설정 (조건부)해서 만들어줄 수 있다
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();
@Builder.Default
를 통해 필드 설정이 없을 경우 객채 생성 시 설정해줄 필드 기본값을 세팅해줄 수 있다!@Builder public class Member { private Integer id; @Builder.Default private String name = "Unnamed"; private int age; @Builder.Default private String email = "Undefined"; }
@Singular
: Collection (List, Set, Map)에 값을 한번에 넣지 않고, 하나씩 주입할 수 있도록 하는게 가능하다Collection에서 Singular List로 만들어서 하나의 element만 넣어주면 collection으로 만들어준다
@Builder public class Member { private Integer id; private String name; private int age; private String email; @Singular private List<String> favorites; } Member baron = Member.builder() .name("Baron") .email("baron@example.com") .favorite("Book") .favorite("Cook") .build();
여기서 왜 .favorite만 해도 되는가?
- @Singular를 사용했을때, 두가지 Method가 생성된다
- A method to add a single item to the list
- you use
.favorite()
to add a single item to the existing library
- you use
- A method to add all items from a collection
- you use
.favorites()
to add a whole collection
- you use
- A method to add a single item to the list
- @Singular를 사용했을때, 두가지 Method가 생성된다
Custom Builder + Validation Logic
@Builder public class Member { private Integer id; private String name; private int age; private String email; public static class MemberBuilder { public MemberBuilder age(int age) { if (age >= 30) { throw new RuntimeException("30세 이상은 설정 불가능합니다."); } this.age = age; return this; } } }
Static Factory Method (정적 팩토리 메서드)
객체 생성 방법을 매우 좁게 정의한다
Factory Method = 객체를 생성 및 반환하는것
- 생성자 대신 정적 팩토리 메서드를 사용하는걸 고려해야한다!
정적 팩토리 메서드를 통한 객체 생성의 장점
- 메서드 이름을 가질 수 있음
- 생성 목적을 이름에 표현할 수 있어 가독성이 좋아진다
- 호출할 때 마다 새로운 객체를 생성할 필요가 없음
- 싱글턴, 혹은 생성해야할 객체 갯수에 제약을 둘 수 있다
- 하위 자료형 객체를 반환할 수 있음
- 상속 사용시 이점이지만 상속보단 조합을 쓰기에 큰 장점은 아니다
- 객체 생성을 캡슐화 할 수 있음
- 메서드 이름을 가질 수 있음
Naming Convension
from
: 하나의 매개 변수를 받아서 객체를 생성of
: 여러개의 매개 변수를 받아서 객체를 생성getInstance
orinstance
: 인스턴스를 생성한다, 이전에 반환했던 것과 같을 수 있다newInstance
orcreate
: 새로운 인스턴스를 생성한다get[OtherType]
: 다른 타입의 인스턴스를 생성한다, 이전에 반환했던 것과 같을 수 있다new[OtherType]
: 다른 타입의 새로운 인스턴스를 생성한다
예시
@AllArgsConstructor(access = AccessLevel.PRIVATE) public class Member { private Integer id; private String name; private int age; private String email; public static Member from(MemberCreateRequestDto requestDto) { return new Member( null, requestDto.getName(), 0, requestDto.getEmail() ); } } MemberCreateRequestDto requestDto = new MemberCreateRequestDto("Baron", "baron@example.com"); // 생성자가 Private 가 되었으므로 외부에서 호출이 불가하다. // Member aaron = new Member(1, "Aaron", 10, "aaron@example.com"); Member baron = Member.from(requestDto);
반응형
'웹개발 > Java' 카테고리의 다른 글
15 - 3. Java - Static (0) | 2024.11.04 |
---|---|
15 - 1. Java - Lombok (0) | 2024.11.04 |
14 - 4. Java - Object 생성자 (0) | 2024.11.04 |
14 - 3. Java의 OOP 문법 - Encapsulation + Inheritence (0) | 2024.11.04 |
14 - 2. Java - JVM (0) | 2024.11.04 |