Skip to content

[1팀 김효정] Chapter 2-2. 디자인 패턴과 함수형 프로그래밍#72

Open
hyodduru wants to merge 15 commits intohanghae-plus:mainfrom
hyodduru:main
Open

[1팀 김효정] Chapter 2-2. 디자인 패턴과 함수형 프로그래밍#72
hyodduru wants to merge 15 commits intohanghae-plus:mainfrom
hyodduru:main

Conversation

@hyodduru
Copy link

@hyodduru hyodduru commented Apr 24, 2025

배포 링크
-refactoring : https://hyodduru.github.io/front_5th_chapter2-2/index.refactoring.html
-origin : https://hyodduru.github.io/front_5th_chapter2-2/index.origin.html

과제의 핵심취지

  • React의 hook 이해하기
  • 함수형 프로그래밍에 대한 이해
  • 액션과 순수함수의 분리

과제에서 꼭 알아가길 바라는 점

  • 엔티티를 다루는 상태와 그렇지 않은 상태 - cart, isCartFull vs isShowPopup
  • 엔티티를 다루는 컴포넌트와 훅 - CartItemView, useCart(), useProduct()
  • 엔티티를 다루지 않는 컴포넌트와 훅 - Button, useRoute, useEvent 등
  • 엔티티를 다루는 함수와 그렇지 않은 함수 - calculateCartTotal(cart) vs capaitalize(str)

기본과제

  • Component에서 비즈니스 로직을 분리하기

  • 비즈니스 로직에서 특정 엔티티만 다루는 계산을 분리하기

  • 뷰데이터와 엔티티데이터의 분리에 대한 이해

  • entities -> features -> UI 계층에 대한 이해

  • Component에서 사용되는 Data가 아닌 로직들은 hook으로 옮겨졌나요?

  • 주어진 hook의 책임에 맞도록 코드가 분리가 되었나요?

  • 계산함수는 순수함수로 작성이 되었나요?

  • Component에서 사용되는 Data가 아닌 로직들은 hook으로 옮겨졌나요?

  • 주어진 hook의 책임에 맞도록 코드가 분리가 되었나요?

  • 계산함수는 순수함수로 작성이 되었나요?

  • 특정 Entitiy만 다루는 함수는 분리되어 있나요?

  • 특정 Entitiy만 다루는 Component와 UI를 다루는 Component는 분리되어 있나요?

  • 데이터 흐름에 맞는 계층구조를 이루고 의존성이 맞게 작성이 되었나요?

심화과제

  • 재사용 가능한 Custom UI 컴포넌트를 만들어 보기

  • 재사용 가능한 Custom 라이브러리 Hook을 만들어 보기

  • 재사용 가능한 Custom 유틸 함수를 만들어 보기

  • 그래서 엔티티와는 어떤 다른 계층적 특징을 가지는지 이해하기

  • UI 컴포넌트 계층과 엔티티 컴포넌트의 계층의 성격이 다르다는 것을 이해하고 적용했는가?

  • 엔티티 Hook과 라이브러리 훅과의 계층의 성격이 다르다는 것을 이해하고 적용했는가?

  • 엔티티 순수함수와 유틸리티 함수의 계층의 성격이 다르다는 것을 이해하고 적용했는가?

과제 셀프회고

과제를 하면서 내가 제일 신경 쓴 부분은 무엇인가요?

이번 과제는 단순한 기능 구현이 아닌, 계층에 맞는 로직 배치와 책임 분리를 고민하는 과제였다.
그래서 처음부터 "컴포넌트가 너무 많은 책임을 지고 있진 않은가?"라는 문제의식을 가지고 시작했고, 그에 따라 로직을 hook, model, UI 컴포넌트로 나누는 데 초점을 맞췄다.

과제를 하며 실제로 겪은 고민과 해결 과정

1. 폴더 구조, 어떻게 나누는 게 맞을까?

초반엔 cart, product, coupon을 도메인 단위로 나누려 했다.
하지만 작업을 진행하면서 product와 coupon은 사실상 CartPage의 일부로 작동하고 있다는 걸 느꼈다.
그래서 오히려 CartPage 중심으로 feature 단위로 묶는 게 더 직관적이라고 판단했고,

  • CartPage > components > ProductList, CartProductList, CouponSection, SummarySection

  • CartPage > hooks > useCart.ts

  • CartPage > models > cart.ts 이런 식으로 구성했다.

이후 admin 페이지도 AdminPage라는 feature 하위에 구성하면서 일관된 구조가 만들어졌다.

2. 훅 vs 모델? 로직을 어디에 넣어야 하지?

getRemainingStock은 cart 상태를 참조해야 해서 useCart 훅 안에 유지.

반면 getMaxApplicableDiscount, calculateItemTotal 같은 함수는 상태와 무관하고 계산만 담당하기 때문에 models/discount.ts로 이동.

처음엔 위치가 모호하게 느껴졌지만, 결국 "상태를 참조하느냐 / 참조하지 않느냐" 를 기준으로 삼으니 분리 기준이 명확해졌다.

3. 컴포넌트 쪼개기 고민

CartPage는 상품 목록, 장바구니 내역, 쿠폰 적용, 주문 요약이라는 4가지 섹션으로 나눌 수 있었다.

처음에는 그냥 item 단위만 분리할까 했지만, 결국 각 덩어리가 명확하게 역할을 가지기 때문에 섹션 단위로 나누기로 결정했다.

ProductList, CartProductList, CartCoupon, CartSummary 식으로 컴포넌트를 나눠서 각각의 책임을 명확히 했다.

4. 도메인끼리 분리할지, 기능별로 묶을지?

cart/product/coupon 도메인 단위로 쪼갤수록 코드는 논리적으로 명확하지만,
페이지 단위로 보는 맥락에서는 오히려 코드 파편화가 심해졌다.
최종적으로는 CartPage라는 feature 단위 하위에서 도메인 요소들을 포함시키는 방향을 택했다. cart가 주가 되고, product, coupon은 거기에 포함되는 느낌으로 정리했다.

아쉬운 점이 있다면?

초반에 너무 구조에 대한 고민을 깊게 하다 보니 작업 속도가 더뎠다. 폴더 구조를 두세 번 뒤엎었고, 고민만 하다가 정작 기능 구현은 늦어지기도 했다. MVC, 클린 아키텍처 등 다양한 아키텍처를 참고하면서 오히려 "지금 이 과제에 맞는 현실적인 구조" 를 잡기 어려웠다.

특히 discount, cart, product 관련 로직이 겹치는 지점에서 위치를 정리하는 데 시간이 많이 소요되었다.

요약하자면,
이번 과제는 단순한 리팩토링 과제가 아니라,
"구조를 어떻게 설계할 것인가" 에 대한 진지한 고민이 담긴 설계 과제였다고 생각합니다.

  • 컴포넌트: UI만 책임지도록

  • 훅: 상태 및 액션만 책임지도록

  • 모델: 순수 계산 로직만 책임지도록

이 원칙을 지키려고 의식적으로 노력했고,
단순히 작동하는 코드가 아닌, 구조적으로 유지보수하기 좋은 코드를 목표로 작성했습니다.

지금까지 했던 과제 중 가장 구조 고민이 많았고, 그래서 가장 많은 배움을 얻은 과제였습니다.

리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문

  1. props drilling이 되더라도 부모 컴포넌트로부터 props를 내려받는 방식 vs 훅을 세세하게 쪼개서 각 컴포넌트에서 직접 사용하는 방식 중 어떤 방식이 더 유지보수나 테스트 측면에서 바람직할지 코치님의 경험을 듣고 싶습니다.

  2. CartPage에 속한 컴포넌트들(ProductList, CartProductList, CartCoupon 등)을 모두 cart feature 안에 두는 방식이 과연 설계적으로 괜찮은 선택인지, 아니면 product나 coupon처럼 독립적인 도메인으로 두는 것이 더 나은지 고민이 많았습니다. 코치님의 기준이 궁금합니다.

  3. calculateItemTotal, getMaxApplicableDiscount 같은 함수는 cart 내부 로직이지만 할인이라는 관점에서 보면 discount 로직과도 관련이 있어 보입니다. 이런 애매한 경우에 함수를 어떤 기준으로 분류하고 위치를 정하는지 판단 기준이 궁금합니다.

  4. 훅 내에서 상태 기반 계산(getRemainingStock)을 하는 함수와, 모델에 두는 순수 계산 함수 간에 분리 기준이 모호하게 느껴지는 경우가 있었는데, 코치님께서는 이런 상황에서 어떻게 처리하는지 궁금합니다.

  5. 실무에서는 pages 폴더와 feature 폴더가 공존할 때, 페이지에 딸린 모든 요소를 feature로 옮기는 편인지, 아니면 단순히 pages 내부에서만 관리하는 구조를 선호하는지 궁금합니다.

  6. calculateItemTotal은 cart 로직인데 할인(discount) 관점에서도 의미가 있다고 생각했는데 코치님께서는 이런 경우 "기능 관점"으로 묶는 걸 선호하는지, 아니면 "도메인 관점"을 더 우선시하실까요??

@hyodduru hyodduru changed the title ㅇㅇ [1팀 김효정] Chapter 2-2. 디자인 패턴과 함수형 프로그래밍 Apr 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant