빌더 패턴 & Optional 활용으로 배우는 객체 생성과 조회 로직

coldrice99·2024년 12월 4일
0
post-thumbnail

1. 코드

Cart cart = cartRepository.findByMemberIdAndMenuIdAndStoreId(member.getId(), request.menuId(), request.storeId())
                .map(existingCart -> {
                    existingCart.updateQuantity(request.quantity());
                    return existingCart;
                })
                .orElseGet(() -> Cart.builder()
                        .member(member)
                        .menu(menu)
                        .store(store)
                        .quantity(request.quantity())
                        .price(request.price())
                        .build());

이 코드는 Optional, 빌더 패턴, 람다 표현식을 활용하여 객체 조회와 생성 로직을 간결하게 처리하는 매우 유용한 예제입니다. 이 코드에서 배운 점과 주요 개념들을 정리했습니다.


2. 주요 개념

  1. Optional:

    • 데이터가 있을 수도, 없을 수도 있는 상황을 처리하는 Java의 클래스.
    • map()orElseGet()을 사용해 조회 결과에 따라 다른 동작을 수행.
  2. 빌더 패턴:

    • 객체 생성 시 복잡한 생성자를 대신해, 메서드 체이닝으로 가독성 있고 직관적인 코드 작성.
  3. 람다 표현식:

    • 간결한 문법으로 코드를 줄이고 가독성을 높임.
  4. 메서드 체이닝:

    • 여러 메서드를 연결해 순차적으로 작업을 처리.

3. 코드 해석

이 코드의 목적은 특정 조건에 맞는 카트를 조회하거나, 없다면 새로 생성하는 것입니다.

1) 카트 조회
cartRepository.findByMemberIdAndMenuIdAndStoreId(member.getId(), request.menuId(), request.storeId())
  • cartRepository에서 특정 멤버, 메뉴, 가게 ID를 조건으로 카트를 검색.
  • 반환값은 Optional:
    • 조회된 카트가 존재 → Optional 내부에 Cart 객체 포함.
    • 조회된 카트가 없음 → 비어 있는 Optional 반환.

2) 조회된 카트가 존재하는 경우 (map)
.map(existingCart -> {
    existingCart.updateQuantity(request.quantity());
    return existingCart;
})
  • Optional.map()은 값이 존재할 때 실행.
  • existingCartOptional 내부의 실제 Cart 객체.
  • 동작:
    1. updateQuantity()로 카트 수량을 업데이트.
    2. 업데이트된 existingCart를 반환.

3) 조회된 카트가 없는 경우 (orElseGet)
.orElseGet(() -> Cart.builder()
        .member(member)
        .menu(menu)
        .store(store)
        .quantity(request.quantity())
        .price(request.price())
        .build());
  • orElseGet()은 값이 없을 때 실행.
  • Cart.builder()로 새 카트를 생성.
  • 동작:
    1. 필요한 필드(member, menu, store, quantity, price)를 설정.
    2. .build() 호출로 새 Cart 객체 생성.

4. 빌더 패턴의 역할

빌더 패턴은 복잡한 객체 생성 로직을 간결하게 처리합니다.
예를 들어:

Cart.builder()
    .member(member)
    .menu(menu)
    .store(store)
    .quantity(request.quantity())
    .price(request.price())
    .build();
  • 필드 설정이 명시적이고 순서에 구애받지 않아 가독성이 뛰어납니다.
  • 특히, 객체가 Immutable(불변)해야 하는 경우에도 빌더 패턴이 유용합니다.

5. Optional과 빌더 패턴의 결합

  • Optional은 데이터 조회 후 결과에 따라 로직을 분기 처리합니다.
  • 빌더 패턴은 조건에 따라 새 객체를 유연하게 생성할 수 있습니다.
  • 이 두 가지를 결합하면 조회-수정-생성 로직을 간단하게 구현할 수 있습니다.

6. 오늘의 배운 점

  1. Optional 활용:

    • 조회 결과가 존재할 때는 map()으로 값 수정.
    • 조회 결과가 없을 때는 orElseGet()으로 기본값 생성.
  2. 빌더 패턴 사용:

    • 복잡한 객체 생성 로직을 간단하고 명확하게 작성.
    • 선택적 필드 초기화 및 가독성 높은 코드 작성 가능.
  3. 람다 표현식과 메서드 체이닝:

    • 간결한 코드 작성과 가독성 향상.

7. 실전에서의 활용

  1. 상태 기반 객체 처리:

    • 조회된 데이터가 존재하면 수정하고, 없으면 생성.
    • 상태 전환 로직을 Optional과 빌더로 쉽게 구현.
  2. Immutable 객체 생성:

    • 빌더 패턴은 객체를 불변하게 설계하는 데 유리.
  3. 코드 간소화:

    • 람다 표현식과 빌더 패턴을 활용해 코드 중복 최소화.

8. 앞으로의 적용

  • 복잡한 객체 생성 시 빌더 패턴을 적극 활용: 특히, 생성자 매개변수가 많거나 선택적 필드가 많을 때.
  • 조회-수정-생성 로직에 Optional 사용: 데이터 상태에 따라 유연하게 처리.
  • 코드 가독성을 높이는 방법을 고민하며, 메서드 체이닝과 람다 표현식 활용을 늘려야겠다.
profile
서두르지 않으나 쉬지 않고

0개의 댓글