π[Backend Development] @Builder
μ @RequiredArgsConstructor
Lombokμ @Builder
μ @RequiredArgsContructor
μ΄λ
Έν
μ΄μ
μ λν΄ μμκ² μ΅λλ€.
π¦ @Builder
μ΄λ
Έν
μ΄μ
β
1. @Builder
μ΄λ
Έν
μ΄μ
μ μΈμ μ¬μ©νλμ?
@Builder
λ κ°μ²΄λ₯Ό μμ±ν λ μ¬μ©νλ©°, νΉν μλμ κ°μ μν©μμ λ§€μ° μ μ©ν©λλ€.
- κ°μ²΄μ μ€μ ν΄μΌ ν νλκ° λ§μ λ
- μΌλΆ νλλ μ νμ μΌλ‘ μ€μ νκ³ μΆμ λ
- κ°μ²΄ μμ± μ μ½λμ κ°λ μ±μ λμ΄κ³ μΆμ λ
- μμ±λ κ°μ²΄μ λΆλ³μ±(Immutability) μ 보μ₯νκ³ μΆμ λ
β
2. @Builder
μ΄λ
Έν
μ΄μ
μ μ΄λμ μ¬μ©νλμ?
@Builder
μ΄λ
Έν
μ΄μ
μ μ£Όλ‘ ν΄λμ€(Class) λλ μμ±μ(Constructor) μμ λΆμ¬μ μ¬μ©ν©λλ€.
// 1. ν΄λμ€μ μ μ©νλ κ²½μ°
@Builder
public class Product {
private Long productId;
private String productName;
// ...
}
// 2. μμ±μμ μ μ©νλ κ²½μ° (νΉμ νλλ§ λΉλμ ν¬ν¨νκ³ μΆμ λ)
public class Product {
private Long productId;
private String productName;
@Builder
public Produc(String productName) {
this.productName = productName;
}
}
β
3. @Builder
μ΄λ
Έν
μ΄μ
μ μ΄λ»κ² μ¬μ©νλμ?
@Builder
λ₯Ό ν΄λμ€μ λΆμ΄λ©΄, Lombokμ΄ μ»΄νμΌ μμ μ μλμΌλ‘ λΉλ μ½λλ₯Ό μμ±ν΄μ€λλ€.
μ°λ¦¬λ μλμ κ°μ΄ λ©μλ 체μ΄λ(Method Chaining) λ°©μμΌλ‘ μ§κ΄μ μΈ μ½λλ₯Ό μμ±ν μ μμ΅λλ€.
Java μ½λ μμ
// λΉλλ₯Ό μ¬μ©νμ¬ κ°μ²΄ μμ±
Product product = Product.builder()
.productName("μ μ ν μ κΈ°λ μ°μ 1L")
.productSaleCost(BigDecimal.valueOf(2500))
.supplier("μμΈ μ°μ ")
.builder(); // λ§μ§λ§μ build()λ₯Ό νΈμΆνμ¬ κ°μ²΄ μμ± μλ£
.νλλͺ
(κ°)
ννλ‘ μνλ κ°λ§ μ€μ νκ³ , μμμ μκ΄μμ΄ μμ λ‘κ² μμ±ν μ μμ΅λλ€.
β
4. @Builder
μ΄λ
Έν
μ΄μ
μ μ μ¬μ©νλμ?
@Builder
λ κ°μ²΄ μμ±μ λ μμ νκ³ , μ μ°νλ©°, μ½κΈ° μ½κ² λ§λ€κΈ° μν΄ μ¬μ©ν©λλ€.
μ΄λ βλΉλ λμμΈ ν¨ν΄(Builder Design Pattern)βμ μλμΌλ‘ ꡬνν΄μ£Όλ κ²μ
λλ€.
-
κ°λ
μ± (Readability) :
new Product(1L, "μ°μ ", ...)
μ²λΌ μμ±μλ₯Ό μ¬μ©νλ κ²λ³΄λ€,builder().productName("μ°μ ").build()
μ²λΌ μ΄λ€ νλμ μ΄λ€ κ°μ΄ λ€μ΄κ°λμ§ λͺ ννκ² μ μ μμ΅λλ€. - μ μ°μ± (Flexibility) : μμ±μμ λ¬λ¦¬ νμν νλλ§ μ νμ μΌλ‘ μ€μ ν μ μκ³ , μμμ ꡬμ λ°μ§ μμ΅λλ€.
-
κ°μ²΄ μΌκ΄μ± / λΆλ³μ± (Consistency / Immutability) :
bulid()
λ©μλκ° νΈμΆλκΈ° μ κΉμ§λ κ°μ²΄κ° μμ±λμ§ μμ΅λλ€. λ°λΌμ μ¬λ¬ μ€μsetter
λ₯Ό μ¬μ©νλ λ°©μκ³Ό λ¬λ¦¬, κ°μ²΄κ° λΆμμ ν μνλ‘ μΈλΆμ λ ΈμΆλ μνμ΄ μμ΅λλ€.
π¦ @RequiredArgsConstructor
μ΄λ
Έν
μ΄μ
@RequiredArgsConstructor
λ νμ μΈμ(final νλ)λ§μ λ°λ μμ±μλ₯Ό μλμΌλ‘ λ§λ€μ΄μ£Όλ Lombok μ΄λ
Έν
μ΄μ
μ
λλ€.
β
1. @RequiredArgsConstructor
μ΄λ
Έν
μ΄μ
μ 무μμΈκ°μ?
@RequiredArgsContructor
λ Lombok λΌμ΄λΈλ¬λ¦¬ μ΄λ
Έν
μ΄μ
μ€ νλλ‘, ν΄λμ€ λ΄μμ final
ν€μλκ° λΆμ΄ μκ±°λ @NonNull
μ΄λ
Έν
μ΄μ
μ΄ λΆμ νλλ§μ μΈμλ‘ λ°λ μμ±μλ₯Ό μ»΄νμΌ μμ μ μλμΌλ‘ μμ±ν΄μ€λλ€.
β
2. @RequiredArgsConstructor
μ΄λ
Έν
μ΄μ
μ μΈμ μ¬μ©νλμ?
μ£Όλ‘ Spring νλ μμν¬μμ μμ±μ κΈ°λ°μ μμ‘΄μ± μ£Όμ (DI, Dependency Injection) μ ꡬνν λ μ¬μ©λ©λλ€.
β
3. @RequiredArgsConstructor
μ΄λ
Έν
μ΄μ
μ μ΄λμ μ¬μ©νλμ?
ν΄λμ€(Class) λ 벨μ μ μΈνμ¬ μ¬μ©ν©λλ€.
β
4. @RequiredArgsConstructor
μ΄λ
Έν
μ΄μ
μ μ΄λ»κ² μ¬μ©νλμ?
μλμ κ°μ΄ ν΄λμ€ μμ μ΄λ Έν μ΄μ μ λΆμ¬μ£ΌκΈ°λ§ νλ©΄ λ©λλ€.
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor // μ΄ μ΄λ
Έν
μ΄μ
μ΄ final νλλ₯Ό μν μμ±μλ₯Ό μλμΌλ‘ λ§λλλ€.
public class ProductService {
private final ProductRepository productRepository; // finalλ‘ μ μΈλ νμ μμ‘΄μ±
private final StockRepository stockRepository; // finalλ‘ μ μΈλ νμ μμ‘΄μ±
private String optionalField; // finalμ΄ μλλ―λ‘ μμ±μμ ν¬ν¨λμ§ μμ
/*
// μλ μμ±μκ° μ»΄νμΌ μμ μ μλμΌλ‘ μμ±λ©λλ€.
public ProductService(ProductRepository productRepository, StockRepository stockRepository) {
this.productRepository = productRepository;
this.stockRepository = stockRepository;
}
*/
}
β 5. μ μ¬μ©νλμ? (Why)
@RequiredArgsConstructor
λ₯Ό μ¬μ©νλ μ΄μ λ μ½λμ κ°κ²°μ±κ³Ό μμ μ±μ λμ΄κΈ° μν¨μ
λλ€.
-
보μΌλ¬νλ μ΄νΈ μ½λ μ κ±° : μμ‘΄μ±μ΄ μΆκ°λκ±°λ λ³κ²½λ λλ§λ€ μμ±μ μ½λλ₯Ό μ§μ μμ ν νμ μμ΄,
final
νλλ₯Ό μ μΈνκΈ°λ§ νλ©΄ λλ―λ‘ μ½λκ° λ§€μ° κΉλν΄μ§λλ€. -
μμ ν κ°μ²΄ μμ± :
final
νλλ λ°λμ μμ± μμ μ μ΄κΈ°νλμ΄μΌ νλ―λ‘, μμ‘΄μ±μ΄ λλ½λλ κ²μ μ»΄νμΌ λ¨κ³μμ λ°©μ§ν μ μμ΅λλ€. -
λΆλ³μ± ν보 :
final
λ‘ μ μΈλ μμ‘΄μ±μ λ³κ²½μ΄ λΆκ°λ₯νλ―λ‘, κ°μ²΄μ λΆλ³μ±μ 보μ₯νμ¬ μ ν리μΌμ΄μ μ μμ μ±μ λμ λλ€.