๐Ÿช kakaotech campus

์นดํ…Œ์ผ | [STEP2 clone coding] 5์ฃผ์ฐจ ๊ณผ์ œ

c0zi 2023. 7. 27. 19:13

5์ฃผ์ฐจ

์นด์นด์˜ค ํ…Œํฌ ์บ ํผ์Šค 2๋‹จ๊ณ„ - BE - 5์ฃผ์ฐจ ํด๋ก  ๊ณผ์ œ

 

๊ณผ์ œ๋ช…

1. ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง

 

๊ณผ์ œ ์„ค๋ช…

์นด์นด์˜ค ์‡ผํ•‘ ํ”„๋กœ์ ํŠธ ์ „์ฒด ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•œ๋‹ค

  • AOP๋กœ ์œ ํšจ์„ฑ๊ฒ€์‚ฌ ์ ์šฉํ•˜๊ธฐ 
  • GlobalExceptionHanlder ๊ตฌํ˜„ํ•˜๊ธฐ
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ -> ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ 
  • ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ •(์ฃผ๋ฌธํ•˜๊ธฐ) -> ์˜ˆ์™ธ์ฒ˜๋ฆฌํ•˜๊ธฐ 
  • ๊ฒฐ์žฌํ•˜๊ธฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„ (์žฅ๋ฐ”๊ตฌ๋‹ˆ๊ฐ€ ๊ผญ ์ดˆ๊ธฐํ™” ๋˜์–ด์•ผํ•จ) 
  • ์ฃผ๋ฌธ๊ฒฐ๊ณผ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ 

 

๊ณผ์ œ ์ƒ์„ธ : ์ˆ˜๊ฐ•์ƒ๋“ค์ด ๊ณผ์ œ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์œ ๋…ํ•ด์•ผํ•  ๊ฒƒ

์•„๋ž˜ ํ•ญ๋ชฉ์€ ๋ฐ˜๋“œ์‹œ ํฌํ•จํ•˜์—ฌ ๊ณผ์ œ ์ˆ˜ํ–‰ํ•ด์ฃผ์„ธ์š”!

 

AOP๊ฐ€ ์ ์šฉ๋˜์—ˆ๋Š”๊ฐ€? โ˜‘๏ธ
GlobalExceptionHandler๊ฐ€ ์ ์šฉ๋˜์—ˆ๋Š”๊ฐ€? โ˜‘๏ธ
์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ์‹œ ๋ชจ๋“  ์˜ˆ์™ธ๊ฐ€ ์ฒ˜๋ฆฌ ์™„๋ฃŒ๋˜์—ˆ๋Š”๊ฐ€? โ˜‘๏ธ
์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ •์‹œ ๋ชจ๋“  ์˜ˆ์™ธ๊ฐ€ ์ฒ˜๋ฆฌ ์™„๋ฃŒ๋˜์—ˆ๋Š”๊ฐ€? โ˜‘๏ธ
๊ฒฐ์žฌํ•˜๊ธฐ์™€ ์ฃผ๋ฌธ๊ฒฐ๊ณผ ํ™•์ธ ์ฝ”๋“œ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋Š”๊ฐ€?

 


1. ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ

 

์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋‹ด๊ธฐ ์˜ˆ์™ธ์ฒ˜๋ฆฌ ๊ณผ์ œ

 

List<Option> options = new ArrayList<>();

for (CartRequest.SaveDTO requestDTO : requestDTOs) {
    int optionId = requestDTO.getOptionId();
    int quantity = requestDTO.getQuantity();

    // 1. ๋™์ผํ•œ ์˜ต์…˜์ด ๋“ค์–ด์˜ค๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ
    // [ { optionId:1, quantity:5 }, { optionId:1, quantity:10 } ]
    if(options.contains(optionId)) {
        throw new Exception400("์ด๋ฏธ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์กด์žฌํ•˜๋Š” ์ƒํ’ˆ์ž…๋‹ˆ๋‹ค. : " + optionId);
    }

    // ์˜ต์…˜ ์กฐํšŒ ๋ฐ ์˜ˆ์™ธ์ฒ˜๋ฆฌ
    Option optionPS = optionJPARepository.findById(optionId).orElseThrow(()
            -> new Exception404("ํ•ด๋‹น ์ƒํ’ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค : " + optionId));
    int price = optionPS.getPrice() * quantity;

    // 2. cartJPARepository.findByOptionIdAndUserId() ์กฐํšŒ -> ์กด์žฌํ•˜๋ฉด ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์ˆ˜๋Ÿ‰์„ ์ถ”๊ฐ€ํ•˜๋Š” ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด์•ผํ•จ. (๋”ํ‹ฐ์ฒดํ‚นํ•˜๊ธฐ)
    Optional<Cart> findExistingCart = cartJPARepository.findByOptionIdAndUserId(optionId, sessionUser.getId());
    if(findExistingCart.isPresent()) {
        Cart existingCart = findExistingCart.get();
        existingCart.update(existingCart.getQuantity() + quantity, existingCart.getPrice() + price);
    } else {
        // 3. [2๋ฒˆ์ด ์•„๋‹ˆ๋ผ๋ฉด] ์œ ์ €์˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๊ธฐ
        Cart cart = Cart.builder().user(sessionUser).option(optionPS).quantity(quantity).price(price).build();
        cartJPARepository.save(cart);
    }
}

 

1) ๋™์ผํ•œ ์˜ต์…˜์ด ๋“ค์–ด์™”์„ ๋•Œ, options ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์–ด ํ•ด๋‹น ์˜ต์…˜ id๊ฐ€ ๋ฆฌ์ŠคํŠธ์— ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ 400 ์—๋Ÿฌ(badRequest)๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ , ์ด๋ฏธ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์กด์žฌํ•˜๋Š” ์ƒํ’ˆ์ด๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.

 

2) ์˜ต์…˜์„ ์กฐํšŒํ•˜๊ณ  ํ•ด๋‹น ์˜ต์…˜ id๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ 404 ์—๋Ÿฌ(notFound)๋ฅผ ๋ฐœ์ƒํ•œ๋’ค ํ•ด๋‹น ์ƒํ’ˆ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌํ•œ๋‹ค.

 

3) ๋˜ํ•œ, JPA Repository๋ฅผ ํ†ตํ•ด ์š”์ฒญ์ด ๋“ค์–ด์˜จ option์˜ ์•„์ด๋””๋ฅผ ์กฐํšŒํ•˜์—ฌ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ์ˆ˜๋Ÿ‰๊ณผ ๊ฐ€๊ฒฉ์„ update์‹œํ‚ค๊ณ  ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๋Š”๋‹ค.  

 


 

2. ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ •

 

์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ • ์˜ˆ์™ธ์ฒ˜๋ฆฌ ๊ณผ์ œ

 

public CartResponse.UpdateDTO update(List<CartRequest.UpdateDTO> requestDTOs, User user) {
    List<Cart> cartList = cartJPARepository.findAllByUserId(user.getId());

    // 1. ์œ ์ € ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์•„๋ฌด๊ฒƒ๋„ ์—†์œผ๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ
    if(cartList.isEmpty()) {
        throw new Exception400("์žฅ๋ฐ”๊ตฌ๋‹ˆ๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค.");
    }

    // 2. cartId:1, cartId:1 ์ด๋ ‡๊ฒŒ requestDTOs์— ๋™์ผํ•œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์•„์ด๋””๊ฐ€ ๋‘๋ฒˆ ๋“ค์–ด์˜ค๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ
    List<Option> checkCartId = new ArrayList<>();

    for(CartRequest.UpdateDTO updateDTO : requestDTOs) {

        int cartId = updateDTO.getCartId();
        if (checkCartId.contains(cartId)) {
            throw new Exception400("๋™์ผํ•œ ์ƒํ’ˆ์ด ์ค‘๋ณต์œผ๋กœ ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค : " + cartId);
        }
        // 3. ์œ ์ € ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์—†๋Š” cartId๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ
        if (cartList.stream().noneMatch(cart -> cart.getId() == updateDTO.getCartId())) {
            throw new Exception404("์œ ์ €์˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” cartId์ž…๋‹ˆ๋‹ค : " + updateDTO.getCartId());
        }
    }

    // ์œ„์— 3๊ฐœ๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ํ”„๋กœ๊ทธ๋žจ์€ ์ž˜๋Œ์•„๊ฐ„๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 1๋ฒˆ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด for๋ฌธ์„ ๋Œ์ง€ ์•Š๊ณ , cartList๊ฐ€ ๋นˆ๋ฐฐ์—ด []๋กœ ์ •์ƒ์‘๋‹ต์ด ๋‚˜๊ฐ.

    return new CartResponse.UpdateDTO(cartList);
} // ๋”ํ‹ฐ์ฒดํ‚น

 

3. ๊ฒฐ์ œํ•˜๊ธฐ ๊ธฐ๋Šฅ ๊ตฌํ˜„ -> ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ดˆ๊ธฐํ™”

 

4. ์ฃผ๋ฌธ๊ฒฐ๊ณผ ํ™•์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„