항해 플러스 7기 7주차

드엔트론프·2025년 12월 7일

항해플러스

목록 보기
7/9
post-thumbnail

7주차

디자인 패턴과 함수형 프로그래밍 그리고 상태 관리 설계

이번주는 디자인 패턴과 함수형 프로그래밍 그리고 상태 관리 설계에 대해 진행했다!

KEEP

  • 심화까지 처음 끝내본 것 같다..!
  • 뭔가 평소 회사 일하면서도 리팩토링할 때 대충 훅으로만 분리하면 좋은거지! 하면서 작업했던 부분이 많았는데, 이제는 어떻게 해야 비즈니스 로직과 뷰 로직의 분리를 더 명확히 할 지에 대해 고민하고 작성할 수 있을 것 같다.
  • 그 부분이 model 계층이었는데, 순수함수로 작성된 model 계층을 통해 훅에는 쓸데없이 비대해지게 작성되지 않으면서, model에 작성된 순수함수로 사이드 이펙트 없이 작업하여 테스트도 하기 쉬운 코드를 작성할 수 있었다.
  const getMaxApplicableDiscount = (item: CartItem): number => {
    const { discounts } = item.product;
    const { quantity } = item;
    
    const baseDiscount = discounts.reduce((maxDiscount, discount) => {
      return quantity >= discount.quantity && discount.rate > maxDiscount 
        ? discount.rate 
        : maxDiscount;
    }, 0);
    
    const hasBulkPurchase = cart.some(cartItem => cartItem.quantity >= 10);
    if (hasBulkPurchase) {
      return Math.min(baseDiscount + 0.05, 0.5); // 대량 구매 시 추가 5% 할인
    }
    
    return baseDiscount;
  };
  • 여기 처음 작성된 getMaxApplicableDiscount 코드는 최대 가능 할인율을 계산하는 로직이다.
  • 이 코드는 내부에서 기본적인 할인율을 계산하나느 baseDiscount와 대량 구매시 추가로 할인이 가능한 hasBulkPurchase 함수가 있다.
  • 문제는 hasBulkPurchase 함수 같은 경우 cart라는, 장바구니 내용을 보게 되는데, 이는 함수 내부에서 cart라는 외부 변수를 참조하며, 동일한 item을 인수로 전달하더라도 cart 변수의 내용이 변경되면 함수의 결과가 달라질 수 있게 된다.
 /**
   * 상품의 기본 할인율 계산 (수량 기반)
   * @param item - 장바구니 아이템
   * @returns 기본 할인율 (0 ~ 1)
   */
  getBaseDiscount: (item: CartItem): number => {
    const { discounts } = item.product;
    const { quantity } = item;

    return discounts.reduce((maxDiscount, discount) => {
      return quantity >= discount.quantity && discount.rate > maxDiscount
        ? discount.rate
        : maxDiscount;
    }, 0);
  },

  /**
   * 대량 구매 보너스 할인율 계산
   * @param cart - 전체 장바구니
   * @returns 대량 구매 보너스 할인율 (0 또는 0.05)
   */
  getBulkPurchaseBonus: (cart: CartItem[]): number => {
    const hasBulkPurchase = cart.some((cartItem) => cartItem.quantity >= 10);
    return hasBulkPurchase ? 0.05 : 0;
  },

  /**
   * 적용 가능한 최대 할인율 계산
   * @param item - 장바구니 아이템
   * @param cart - 전체 장바구니 (대량 구매 체크용)
   * @returns 최대 할인율 (0 ~ 0.5, 최대 50%)
   */
  getMaxApplicableDiscount: (item: CartItem, cart: CartItem[]): number => {
    const baseDiscount = cartModel.getBaseDiscount(item);
    const bulkBonus = cartModel.getBulkPurchaseBonus(cart);

    // 기본 할인 + 대량 구매 보너스, 최대 50% 제한
    return Math.min(baseDiscount + bulkBonus, 0.5);
  },
  • 각 함수는 각각의 입력값 item, cart이라는 명시적인 매개변수로 변경해, 동일한 입력에 대해 항상 동일한 출력을 보장하는 순수 함수를 정의하였다.
  • 이는 테스트하기도 좋은 코드가 되며, 동일한 입력값, 동일한 출력값을 가지게 되는 순수 함수가 됐다.

2. jotai 쓰기

  • zustand나 context는 평소에 종종 쓰기에, 써보지 않았던 jotai를 사용했다.
  • jotai는 특히 소규모 프로젝트에 잘 어울린다고 한다.
// atoms/cart.ts
export const cartAtom = atomWithStorage<CartItem[]>("cart", []);

export const totalItemCountAtom = atom((get) => {
  const cart = get(cartAtom);
  return cart.reduce((sum, item) => sum + item.quantity, 0);
});
// hooks/useCart.ts

export const useCart = () => {

  const [cart, setCart] = useAtom(cartAtom);
  const totalItemCount = useAtomValue(totalItemCountAtom);

  ...
  • 전역변수를 설정함으로써, 불필요한 props drilling을 방지할 수 있었다.

Problem

  • 이번 과제도 지난주처럼 자유도가 있었다고 볼 수 있다.
  • 내가 어디까지 리팩토링 해야할까?에 대한 명확한 기준이 세워지지 않아 스스로 만족하면 그만둬도 되나? 이게 다 된걸까? 어딜 더 수정하면 좋을까?에 대한 고민들을 했지만 모두 다 이룬 것 같지 않다.

Try

  • 적당히에 만족하고 안주하지 말고 끝까지 하는 열정을 보이자.
  • 잠을 조금은 이겨내보려 노력하자!

7주차 여러 일

3모각코

  • 월요일, 화요일, 금요일 3일이나 모각코를 했다 ㅋㅋㅋㅋ
  • 이정도면 그냥 모친놈?

월요일

  • 월요일 모각코 시작전 저녁으로 진~~짜 맛있는 야채곱창을 먹었다.. 기절할 뻔

- 볶음밥도 못참지.. 
  • 야채곱창 먹고 카페 가려다 갑자기 붕어빵 얘기가 나와 붕어빵을 먹었다.
  • 먹고 카페에 갔더니 어라, 카페에 사람 다 차버렸다 ㅠㅠ 다른 곳 찾다가 찾은 곳이 붕어빵 옆 카페
  • 지나가며 붕어빵 한 번 더 사먹었다 ㅋㅋㅋ 올해 첫 붕어빵 성공적!

화요일

  • 그나마 가까운.. 신림에서의 모각코를 했다.
  • 많이들 안오기도 했고, 막차 전까지 결국 작업하는 시간이 그리 길지 않음에도 모각코를 하면 확실히 짧은 시간동안 집중할 수 있게 되는 것 같다. 좋음!

  • 울팀 학습 메이트가 여행 갔다와서 과자도 사다줌.. ㅠㅠ 따수운 1팀

금요일

  • 어쩌다 대규모 회식 + 밤샘팟이 돼버린 금요일 모각코.
  • 우리팀 말고 2팀도 대부분이 참석해 다같이 저녁을 먹고, 우리 팀은 멘토링이 있어 먼저 카페로 갔다.

  • 우당탕탕 멘토링 끝나고나니 새벽 2시..
  • 멘토링 듣는 와중에도 심화과제 열심히 하고, 제출할 수 있었다 굳!
  • 5시, 다들 첫 차를 기다리다 첫차 즈음 아침으로 뼈해장국 먹었다.
  • 다들 집가고, 나는 발제를 위해..(이게 뭐라고) 근처 사우나에 혼자 갔다
  • 확실히 서울 사우나라 비싸고 작은 시설이지만 갖출건 다 갖춰진 아주 좋은 사우나 굳굳
  • 수면실에서 적당히 자다가 나와서 발제 듣고 졸다가~ 팀 회의를 마지막으로 집에 돌아왔다.
  • 거의 1박2일 어디 여행 갔다 온 느낌

시간이 어째 가는 지 모르게 어느새 7주차 끝나고 8주차 시작이다.. 언제 지나가나~ 해도 벌써 끝이 다와간다.. 남은 주차도 후회하지않게 화이팅하자!

profile
왜? 를 깊게 고민하고 해결하는 사람이 되고 싶은 개발자

0개의 댓글