과제 체크포인트
기본과제
- 코드가 Prettier를 통해 일관된 포맷팅이 적용되어 있는가?
- 적절한 줄바꿈과 주석을 사용하여 코드의 논리적 단위를 명확히 구분했는가?
- 변수명과 함수명이 그 역할을 명확히 나타내며, 일관된 네이밍 규칙을 따르는가?
- 매직 넘버와 문자열을 의미 있는 상수로 추출했는가?
- 중복 코드를 제거하고 재사용 가능한 형태로 리팩토링했는가?
- 함수가 단일 책임 원칙을 따르며, 한 가지 작업만 수행하는가?
- 조건문과 반복문이 간결하고 명확한가? 복잡한 조건을 함수로 추출했는가?
- 코드의 배치가 의존성과 실행 흐름에 따라 논리적으로 구성되어 있는가?
- 연관된 코드를 의미 있는 함수나 모듈로 그룹화했는가?
- ES6+ 문법을 활용하여 코드를 더 간결하고 명확하게 작성했는가?
- 전역 상태와 부수 효과(side effects)를 최소화했는가?
- 에러 처리와 예외 상황을 명확히 고려하고 처리했는가?
- 코드 자체가 자기 문서화되어 있어, 주석 없이도 의도를 파악할 수 있는가?
- 비즈니스 로직과 UI 로직이 적절히 분리되어 있는가?
- 코드의 각 부분이 테스트 가능하도록 구조화되어 있는가?
- 성능 개선을 위해 불필요한 연산이나 렌더링을 제거했는가?
- 새로운 기능 추가나 변경이 기존 코드에 미치는 영향을 최소화했는가?
- 코드 리뷰를 통해 다른 개발자들의 피드백을 반영하고 개선했는가?
- (핵심!) 리팩토링 시 기존 기능을 그대로 유지하면서 점진적으로 개선했는가?
심화과제
- 변경한 구조와 코드가 기존의 코드보다 가독성이 높고 이해하기 쉬운가?
- 변경한 구조와 코드가 기존의 코드보다 기능을 수정하거나 확장하기에 용이한가?
- 변경한 구조와 코드가 기존의 코드보다 테스트를 하기에 더 용이한가?
- 변경한 구조와 코드가 기존의 모든 기능은 그대로 유지했는가?
- (핵심!) 변경한 구조와 코드를 새로운 한번에 새로만들지 않고 점진적으로 개선했는가?
과제 셀프회고
디코방에 다른분들이 공유해준 ai사용법을 토대로 리펙토링 진행. ex) 토스 컨벤션.mdc, ai에게 컨벤션 먹이기 등등..
→ 자료들과 ai만 믿고 리펙토링을 하면할수록 테스트코드를 통과하지 못하기 시작하고, 리펙토링은 커녕 이상한 소리만 늘어노음, 4시간동안 잘 달래도보고 해봤지만 결과는 그대로,,
아무리 자료가 좋고 ai가 뛰어나다고 하더라도, ai는 시킨 것을 잘 하는 것, 결국 시킨 사람이 자기가 시키는 것에 대해 잘 알아야하고,
이때부터 리펙토링을 어떻게 할지 고민을 열심히 함.
리펙토링에 앞서 구현된 기능들을 구분해봄.
- 상품&재고 관리
- 상품 메타데이터(가격, 기본 재고, 개별 할인율) 조회
- 재고 감소·복구 로직
- 재고 상태 플래그 - 품절 / 재고부족 표시
- 장바구니 도메인
- 상품 추가/삭제 수량 변경
- 중복 상품 합치기, 수량 0 → 자동 제거
- 카트 내 총 수량, 항목 리스트 관리
- 가격·할인 엔진
- 개별 상품 할인(10개 이상)
- 전체 수량 할인(30개 이상)
- 특별 할인
- 화요일 10%
- 번개세일 20%
- 추천할인 5%
- 중복 규칙 및 SUPER SAVE (25%)
- 가장 큰 할인율 우선 중복 계산 로직
- 포인트 적립 시스템
- 기본 적립 (결제 금액 0.1%)
- 추가 적립
- 화요일 2배
- 세트/풀세트 보너스
- 수량별 보너스(10/20/30개)
- 적립 내역 집계 표시
- 프로모션 타이머 이벤트 스케줄러
- 무작위 지연 후 번개세일/추천할인 시작
- 주기적(30s/60s) 상품 선정 할인 적용
- 알림,드롭다운 아이콘 갱신
- UI 컴포넌트 & 상태 표시
- 메인 레이아웃(상품 선택, 장바구니, 주문 요약)
- 상품 드롭다운, 할인 재고 강조 스타일
- 장바구니 카드(+/-, Remove 버튼, 스타일 규칙)
- 주문 요약 패널(소계·할인·배송·최종 금액·포인트)
- 도움말 모달 & 인터랙션
- 고정 버튼 클릭 → 슬라이드 모달 열기/닫기
- 배경 클릭 / X버튼으로 닫기
- 할인·포인트 정책 안내 콘텐츠
- 예외 처리 & 알림(Error Handling)
- 재고 부족 경고(alert)
- 빈 장바구니 기본 UI 유지
- 동시 할인 상한(최대 25 %) 로직
- 전역 상태 관리 & 실시간 계산(Reactivity)
- 모든 변동 시 금액·포인트·재고·카운터 즉시 업데이트
- 깜빡임 없는 DOM 렌더링(성능·UX 요건)
- 테스트 & 품질 보증(Test Harness)
- Vitest + @testing-library 시나리오 기반 검증
- CI 통과를 목표로 한 안전 리팩터링 가이드라인
리팩터링 아키텍처 초안
src/
├─ app/ # 애플리케이션 부트스트랩
│ └─ index.js
│
├─ domain/ # 비즈니스 로직 (순수 함수/클래스)
│ ├─ product/
│ │ ├─ Product.js
│ │ └─ Inventory.js
│ ├─ cart/
│ │ ├─ Cart.js
│ │ └─ CartItem.js
│ ├─ pricing/
│ │ ├─ DiscountPolicy.js
│ │ ├─ SpecialDiscounts.js
│ │ └─ PricingEngine.js
│ └─ loyalty/
│ ├─ PointCalculator.js
│ └─ BonusRules.js
│
├─ infra/ # 브라우저 의존 I/O, 타이머, 알림
│ ├─ PromoScheduler.js
│ └─ AlertService.js
│
├─ presenters/ # DOM 조작 (Service ↔ UI 어댑터)
│ ├─ CartPresenter.js
│ ├─ ProductSelectorPresenter.js
│ └─ SummaryPresenter.js
│
├─ ui/ # 순수 HTML 템플릿/뷰 헬퍼
│ ├─ components/
│ │ ├─ CartItemCard.js
│ │ ├─ DropdownOption.js
│ │ └─ HelpModal.js
│ └─ style/ # Tailwind + 커스텀 클래스
│
└─ tests/ # 기존 basic/advanced 테스트 이동
└─ cart.feature.test.js
실제 파일을 바로 옮기기보다, 새로운 모듈을 만들고, 기존 코드에서 단계적으로 이관/교체 → 테스트 통과 확인 → 다음 단계 진행하는 스트랭글 패턴 방식으로 진행.
세부 모듈 설명
- domain/product
- Product : id, name, price, baseStock, unitDiscount 보유
- Inventory : 재고량 관리 + 감소·복구 메서드
- domain/cart
- Cart : 상품 목록 Map(id→CartItem), add/remove/changeQty, getTotals()
- CartItem : productRef, qty
- domain/pricing
- DiscountPolicy : “적용 가능 여부 & 할인율 반환” 인터페이스
- SpecialDiscounts : 화요일·SUPER SALE 등 정책 집합
- PricingEngine : 정책 우선순위·중복 규칙 계산
- domain/loyalty
- PointCalculator : 결제금액·보너스 룰 입력 → pointResult
- BonusRules : 세트·수량·화요일 등 규칙 모음
- infra/
- PromoScheduler : setTimeout / setInterval 로 특가 발생, Domain 업데이트 후 Presenter에 이벤트 발행
- AlertService : window.alert 추상화(테스트 더블 교체 가능)
- presenters/
- Domain → UI 동기화 담당. 예) CartPresenter.update(cart) 가 DOM 변화를 호출
- 단위테스트 시 DOM 모킹으로 검증 가능
- ui/components
- 완전 Dumb Component: props ↔ innerHTML 렌더만 수행
위 정보를 토대로 리펙토링을 진행할 때 ai에게 TODO를 만들어 달라고 한 뒤, TODO를 하나씩 만들때마다 코드를 확인하고 테스트를 돌려보는 방식으로 리펙토링 진행함.
확실히 이전에 ai를 자료와 ai의 성능에 기대어 리펙토링하는 것 보다 훨씬 더 빠르고 잘 만들어졌다. ai를 사용하더라도 그 사용 이유가 명확해야하고, TODO로 스케일을 나누어 개발하는 것이 좋았다.
과제를 하면서 내가 제일 신경 쓴 부분은 무엇인가요?
코드 안짜고 과제 통과하기!
과제를 다시 해보면 더 잘 할 수 있었겠다 아쉬운 점이 있다면 무엇인가요?
초반에 다른 분들이 공유주신 자료들과 ai의 성능에 기대어 개발만 했던 것에서 시간을 너무 많이 날려먹어 아쉽다.
리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문 편하게 남겨주세요 :)
초반에 ai로 basic파일 던져주고 리펙토링해달라고 했는데 굉장히 많은 토큰을 잡아먹더라구요, 대용량 파일을 리펙토링하는데 토큰을 효율적으로 사용할 수 있는 방법이 뭐가 있을까요?
폴더 구조를 기능기반으로 분리해두었는데, 초반에 기능이 별로 없을 때에는 그렇게 좋지않는 폴더 구조인 것 같습니다. 프로젝트를 간단하게 만들때나 프로젝트를 키워나갈때 참고할만한 폴더 구조가 뭐가 있을까요?
과제 피드백
안녕하세요 정우님! 4주차 과제 잘 진행해주셨네요 ㅎㅎ 다만 심화과제까지 할 시간적 여유가 부족했나보네요 ㅠㅠ
일단 현재 진행된 모습을 보니 클린 아키텍쳐로 구성해주신 것 같아요! 이렇게 구성했을 때의 장단점을 정우님께서 기록해주시면 어땠을까 싶네요..!
저의 개인적인 시야로 봤을 때 infra와 domain은 구분이 되어 있으나, infra의 코드가 외부 의존을 하는게 아니라 domain만 의존하고 있어서 사실 없어도 되는 레이어 아닌가!? 라는 생각이 들어요 ㅎㅎ
특별한 질문은 없어서 여기서 마무리하도록 하겠씁니다!