Yangs1s 님의 상세페이지[5팀 양성진] Chapter 2-1. 클린코드와 리팩토링

과제 체크포인트

기본과제

  • 코드가 Prettier를 통해 일관된 포맷팅이 적용되어 있는가?
  • 적절한 줄바꿈과 주석을 사용하여 코드의 논리적 단위를 명확히 구분했는가?
  • 변수명과 함수명이 그 역할을 명확히 나타내며, 일관된 네이밍 규칙을 따르는가?
  • 매직 넘버와 문자열을 의미 있는 상수로 추출했는가?
  • 중복 코드를 제거하고 재사용 가능한 형태로 리팩토링했는가?
  • 함수가 단일 책임 원칙을 따르며, 한 가지 작업만 수행하는가?
  • 조건문과 반복문이 간결하고 명확한가? 복잡한 조건을 함수로 추출했는가?
  • 코드의 배치가 의존성과 실행 흐름에 따라 논리적으로 구성되어 있는가?
  • [] 연관된 코드를 의미 있는 함수나 모듈로 그룹화했는가?
  • ES6+ 문법을 활용하여 코드를 더 간결하고 명확하게 작성했는가?
  • 전역 상태와 부수 효과(side effects)를 최소화했는가?
  • [] 에러 처리와 예외 상황을 명확히 고려하고 처리했는가?
  • 코드 자체가 자기 문서화되어 있어, 주석 없이도 의도를 파악할 수 있는가?
  • 비즈니스 로직과 UI 로직이 적절히 분리되어 있는가?
  • 코드의 각 부분이 테스트 가능하도록 구조화되어 있는가?
  • 성능 개선을 위해 불필요한 연산이나 렌더링을 제거했는가?
  • 새로운 기능 추가나 변경이 기존 코드에 미치는 영향을 최소화했는가?
  • 코드 리뷰를 통해 다른 개발자들의 피드백을 반영하고 개선했는가?
  • (핵심!) 리팩토링 시 기존 기능을 그대로 유지하면서 점진적으로 개선했는가?

심화과제

  • 변경한 구조와 코드가 기존의 코드보다 가독성이 높고 이해하기 쉬운가?
  • 변경한 구조와 코드가 기존의 코드보다 기능을 수정하거나 확장하기에 용이한가?
  • 변경한 구조와 코드가 기존의 코드보다 테스트를 하기에 더 용이한가?
  • 변경한 구조와 코드가 기존의 모든 기능은 그대로 유지했는가?
  • (핵심!) 변경한 구조와 코드를 새로운 한번에 새로만들지 않고 점진적으로 개선했는가?

과제 셀프회고

과제 배포 링크 https://yangs1s.github.io/front_6th_chapter2-1/

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

저는 바이브 코딩으로 과제를 진행했습니다. 주로 AI에 대한 내용을 신경썼습니다.

작은단위로 질문하기

스크린샷 2025-07-30 오후 8 18 15

일단 AI가 맘대로 하거나, 이상하게 해석해서 코드를 이상하게 고치려고 하는점, 이게 가장 신경쓰였습니다 그래서 테오코치님이나 준일코치님, 저희팀 학매석호님도 공통적으로는 작게작게 세분화해서 질문을 하면서 접근하라는게 가장 공통적인 의견이여서 이런 부분은 신경을 쓰면서 했던거 같아요. 그리고 기본적으로 어떤 방향성을 가지면서 코드를 리팩토링하고 수정할지 docs를 이용해서, 이걸 AI에게 학습시키는 방식으로 과제의 목표에 벗어나지 않게끔 이용했던거 같습니다.

프롬프트 잘 작성하기

멘토링 시간 이후 좀더 프롬프트를 세세하게 작성해서 작업해야겠다 생각하여

image

클로드안에 프로젝트를 만들고, 안에 프로젝트 지식을 채워서 얘가 이걸 기반으로 코드를 어떻게 해줄지 설명을 해주고 알려줍니다.. 이 지식을 기반으로 혼자서 생각을 하고 알려주기 시작하더라고요, 별 이상한 질문에도 이거와 연관해서 자꾸 얘기해주고 그만큼 성능 괜찮다라고 느꼈습니다.

코드 설계 원칙은 무조건적으로 입각할수 있게 제일 먼저 적어두었고, 최대한 상세하게 알수 있을만큼 적어놨습니다. 하지만 이거도 완전하게 잘 되는건 아니였습니다. 멋대로 자꾸 로직을 스스로 만들어서 작성한다거나, 여러모로 완벽하게 얘네가 다 해줄순 없구나 더 체감하게 됐습니다.

과제를 다시 해보면 더 잘 할 수 있었겠다 아쉬운 점이 있다면 무엇인가요?

  1. 제가 더 잘할수 있었을지는 모르겠지만, 갑자기 이걸 손코딩으로 한번 해보고싶다는 아쉬운 마음은 있었습니다.
  2. 더 코드를 파악해보고 체계적으로 접근했어야 했는데 그렇게 못했던점
  3. 필요할 때마다 타입을 추가했는데:
  • 처음부터 모든 도메인 타입을 완성하고 시작
  • Product, CartItem, Order, Discount 등 비즈니스 모델을 먼저 정의
  • API 응답 타입, 컴포넌트 Props 타입을 더 세밀하게
  1. basic에서는 전역 변수를 넘 남발한거 같아요.
  • 캡슐화를 통한 상태보호 했어야했는데 급급하게 하느라 이런걸 너무 신경쓰지 않았다는 점
  • 정확하게 몰라서 조금 더 도전적으로 찾아보면서 해봤어야 했는데 너무 통과에만 포커스를 맞춰버린점.
  1. 단일 책임 원칙을 잘 못지킨 함수들이 있던거 같습니다.

전반적으로 좀 어려웠습니다. AI를 너무 쓰니까 오히려 고쳐야할거도 수정할거도 너무 많이 나왔다는점? AI의 답변을 판별할 능력이 중요하다고 생각하는데 오히려 적정한 기준이 있으면서 지식에 대한 베이스가 어느정도 갖춰져야 한다고 생각하고 그런점들이 저 자신에게 너무 아쉬웠습니다.

리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문 편하게 남겨주세요 :)

export const ShoppingPage: React.FC<ShoppingPageProps> = ({ onCartCountChange }) => {

  const [products, setProducts] = useState(initialProducts);
  

  const [cartItems, setCartItems] = useState<Product[]>([]);


  const {
    selectedProduct,
    stockInfo,
    handleProductChange,
    handleAddToCart,
    handleQuantityChange,
    handleRemoveItem,
    handleCheckout
  } = useCartHandlers(products, setProducts, cartItems, setCartItems);

  const {
    subTotal,
    finalTotal,
    discountRate,
    loyaltyPoints,
    bonusPointsDetail,
    totalStock,
    cartCount,
    itemDiscounts,
    totalItemCount,
    isTuesdayApplied
  } = useCartCalculations(cartItems, products);


  React.useEffect(() => {
    onCartCountChange(cartCount);
  }, [cartCount, onCartCountChange]);


  return (
    <>

      <Layout
        leftContent={
          <>
            <SelectorContainer>
              <ProductSelector
                products={products}
                selectedProduct={selectedProduct}
                onProductChange={handleProductChange}
                onAddToCart={handleAddToCart}
                stockInfo={stockInfo}
              />
              
              {/* 재고 정보 */}
              <StockInfo 
                products={products}
                totalStock={totalStock}
              />
            </SelectorContainer>
            
            <CartDisplay>
              <h3 className="text-lg font-semibold mb-4">장바구니</h3>
              {cartItems.length > 0 ? (
                <div>
                  {cartItems.map(item => (
                    <CartPrices 
                      key={item.id}
                      product={item} 
                      quantity={item.quantity}
                      onQuantityChange={handleQuantityChange}
                      onRemove={handleRemoveItem}
                    />
                  ))}
                </div>
              ) : (
                <p className="text-gray-500 text-sm">장바구니가 비어있습니다.</p>
              )}
            </CartDisplay>
          </>
        }
        rightContent={
          <OrderSummary
            cartItems={cartItems.map(item => ({
              id: item.id,
              name: item.name,
              quantity: item.quantity,
              price: item.val
            }))}
            subTotal={subTotal}
            finalTotal={finalTotal}
            loyaltyPoints={loyaltyPoints}
            bonusPointsDetail={bonusPointsDetail}
            isTuesdayApplied={isTuesdayApplied}
            discounts={itemDiscounts}
            totalItemCount={totalItemCount}
            discountRate={discountRate}
            itemCount={cartCount}
            onCheckout={handleCheckout}
          />
        }
      />
      
      {/* 상태 메시지 */}
     
    </>
  );
};

  1. 너무 많은 props 전달이 괜찮은가여? OrderSummary에 10개 이상이 props 전달을 하는데 더 나은 데이터 구조화 방법이 있을까요?
  2. Layout 컴포넌트 구조가 적절한가요? leftContent/rightContent로 나눴는데 이런 식으로 구조를 나눠보는게 괜찮은가요?
  3. 타입 정의 위치 기준이 따로 있을까요? 언제 types/ 폴더에 빼고, 언제 컴포넌트 내부에 두나요? 따로 이런걸 판단하거나 하는 기준이 있을까요?

과제 피드백

안녕하세요 성진님! 4주차 과제 잘 진행해주셨네요 ㅎㅎ 고생하셨습니다!

너무 많은 props 전달이 괜찮은가여? OrderSummary에 10개 이상이 props 전달을 하는데 더 나은 데이터 구조화 방법이 있을까요?

현재 props를 관심사에 따라 그룹핑해주면 어떨까 싶어요. 일단 제가 임의로 추출한건 4가지인데요

<OrderSummary
	장바구니데이터={장바구니데이터}
	할인율데이터={할인율데이터}
	포인트데이터={포인트데이터}
	onCheckout={handleCheckout}
/>

이렇게 네 가지로 분리해서 넘겨주면 어떨까 싶네요!

꼭 1depth로 모든걸 다 처리할 필요는 없답니다 ㅎㅎ

Layout 컴포넌트 구조가 적절한가요? leftContent/rightContent로 나눴는데 이런 식으로 구조를 나눠보는게 괜찮은가요?

적절함을 판단하는 기준이 뭘까요? 이런 질문은 사실 모호해서 답변드리기가 어려워요. 다음부터는 "저는 이러이러한 기준으로 적절함을 판단했고, 그래서 이렇게 작성했어요. 괜찮을까요?" 처럼 질문을 주셔야 답변드리기가 수월하답니다!

일단 저의 기준을 토대로 이야기드리자면, 저는 "다양한 요구사항에 대응할 수 있는가"를 기준으로 판단할 것 같아요. 여기서 가령 지금은 PC 버전의 UI만 대응할 수 있는데요, 만약에 모바일 버전의 UI를 동시에 대응해야 한다면 left,right 라는 이름이 병목이 될 수 있겠죠!? 모바일에서는 좌/우 UI가 아니라 상/하 UI로 표현이 되어야 할테니까요 ㅎㅎ

타입 정의 위치 기준이 따로 있을까요? 언제 types/ 폴더에 빼고, 언제 컴포넌트 내부에 두나요? 따로 이런걸 판단하거나 하는 기준이 있을까요?

현재 정의한 type과 가장 가까운 곳에 위치시키면 좋답니다! 가령, 내가 작성한 코드를 라이브러리 혹은 모듈로 똑 떼어서 다른 프로젝트에 적용한다고 했을 때 이게 깔끔하게 도려내져야해요. 함께 쓰이는 코드의 위치가 멀리 있으면 이걸 분리하기가 굉장히 어렵답니다 ㅎㅎ 즉, 응집도가 낮은거죠.

응집도가 높다면 라이브러리/모듈 등으로 분리하기가 굉장히 쉬워요!


기본과제에서 작성한 코드를 심화과제에서도 잘 사용해주신 모습이 인상적이네요! 회고만 더 체계적으로 작성되어있다면 완벽했을 것 같아요..!