우당탕탕 기술블로그
[회고록] 우아한 테크코스 6기 프리코스 4주차 회고 본문
목차
GitHub - hyzzzzy/javascript-christmas-6-hyzzzzy
Contribute to hyzzzzy/javascript-christmas-6-hyzzzzy development by creating an account on GitHub.
github.com
🎄 프로모션 구현 목록
- 방문 날짜 입력 및 유효성 검사
- 1 이상 31 이하의 숫자가 아닌 경우
- (추가) 자연수가 아닌 경우
- 주문할 메뉴, 개수 입력 및 유효성 검사
- 메뉴판에 없는 메뉴를 입력한 경우
- 메뉴의 개수를 1 이상의 숫자로 입력하지 않은 경우
- 메뉴 형식이 예시와 다른 경우
- 중복 메뉴를 입력한 경우
- (추가) 음료만 주문한 경우
- (추가) 메뉴의 개수가 20개 초과인 경우
- 주문 메뉴 출력
- 할인 전 총주문 금액 계산 및 출력
- 증정 메뉴 계산 및 출력
- 할인 전 총 주문 금액이 12만 원 이상인 경우 샴페인 1개 증정
- 증정 이벤트에 해당하지 않는다면 ‘없음’ 출력
- 혜택 내역 계산 및 출력
- 주문 금액이 1만 원 이상부터 혜택 시작, 적용된 혜택만 출력
- 주문 금액이 1만 원 미만이라면 ‘없음’ 출력
- 크리스마스 디데이 할인
- 1일(1000원)부터 시작해서 25일(3400원)까지 100원씩 증가하여 계산
- 평일 할인
- 일, 월, 화, 수, 목: 디저트 메뉴 1개당 2023원 할인
- 주말 할인
- 금, 토: 메인 메뉴 1개당 2023원 할인
- 특별 할인
- 별 있는 날짜라면 총주문 금액에서 1000원 할인
- 별 있는 날짜: 3, 10, 17, 24, 25, 31일
- 증정 이벤트(샴페인 1개)
- 증정 메뉴에 샴페인이 있다면 25000원 할인
- 총혜택 금액 계산 및 출력
- 할인 후 예상 결제 금액 계산 및 출력
- 12월 이벤트 배지 계산 및 출력
- 총 혜택 금액이 5000원 이상인 경우부터 적용
- 이벤트 배지가 부여되지 않는다면 ‘없음’ 출력
- 5000원 이상: 별
- 1만 원 이상: 트리
- 2만 원 이상: 산타
🎄 폴더 구조
__tests__
┣ domain
┃ ┣ BadgeEventTest.js
┃ ┣ DDayDiscountTest.js
┃ ┣ GiftEventDiscountTest.js
┃ ┣ OrderTest.js
┃ ┣ PromotionTest.js
┃ ┣ SpecialDiscountTest.js
┃ ┗ WeekDiscountTest.js
┣ utils
┃ ┣ ConstantsUtilTest.js
┃ ┣ DateValidatorTest.js
┃ ┣ MenuValidatorTest.js
┃ ┣ UtilTest.js
┃ ┗ ValidatorTest.js
┗ ApplicationTest.js
src
┣ constants
┃ ┣ event.js
┃ ┣ menu.js
┃ ┣ message.js
┃ ┗ setting.js
┣ domain
┃ ┣ BadgeEvent.js
┃ ┣ DDayDiscount.js
┃ ┣ GiftEvent.js
┃ ┣ Order.js
┃ ┣ Promotion.js
┃ ┣ SpecialDiscount.js
┃ ┗ WeekDiscount.js
┣ utils
┃ ┣ ConstantsUtil.js
┃ ┣ DateValidator.js
┃ ┣ MenuValidator.js
┃ ┣ Util.js
┃ ┗ Validator.js
┣ view
┃ ┣ InputView.js
┃ ┗ OutputView.js
┣ App.js
┗ index.js
🎄 테스트 케이스 목록
- 주문 테스트
- 주문한 해당 카테고리 메뉴 계산 메서드
- 원하는 계산 결과와 정확히 일치해야 한다.
- 주문한 모든 메뉴 계산 메서드
- 원하는 계산 결과와 정확히 일치해야 한다.
- 예상 결제 금액 계산 메서드
- 원하는 계산 결과와 정확히 일치해야 한다.
- 주문한 해당 카테고리 메뉴 계산 메서드
- 프로모션 테스트
- 혜택 총액 계산 메서드
- 예상한 총혜택 금액과 정확히 일치해야 한다.
- 혜택 내역 반환 메서드
- 모든 혜택 내역들을 객체 형태로 반환해야 한다.
- 혜택 총액 계산 메서드
- 증정 이벤트 테스트
- 증정 이벤트 여부 계산 메서드
- 할인 전 총주문 금액이 12만 원 이상이라면 true를 반환해야 한다.
- 할인 전 총주문 금액이 12만 원 미만이라면 false를 반환해야 한다.
- 증정 이벤트 할인 계산 메서드
- 할인 전 총주문 금액이 12만 원 이상이라면 -25000을 반환해야 한다.
- 할인 전 총주문 금액이 12만 원 미만이라면 0을 반환해야 한다.
- 증정 이벤트 여부 계산 메서드
- 크리스마스 디데이 할인 테스트
- 크리스마스 디데이 할인 계산 메서드
- 총주문 금액 1만 원 미만이라면 0을 반환해야 한다.
- 크리스마스가 지났다면 0을 반환해야 한다.
- 1만 원 이상이고 크리스마스가 지나지 않았다면 원하는 계산 결과와 정확히 일치해야 한다.
- 크리스마스 디데이 할인 계산 메서드
- 평일, 주말 할인 테스트
- 주문한 해당 카테고리 할인 계산 메서드
- 유효하지 않은 카테고리라면 매개변수 discount의 값과 일치해야 한다.
- 유효한 카테고리라면 원하는 계산 결과와 정확히 일치해야 한다.
- 평일 할인 계산 메서드
- 총주문 금액 1만 원 미만이라면 0을 반환해야 한다.
- 예약 날이 주말이라면 0을 반환해야 한다.
- 총주문 금액이 1만 원 이상이고 예약 날이 평일이라면 원하는 계산 결과와 정확히 일치해야 한다.
- 주말 할인 계산 메서드
- 총주문 금액 1만 원 미만이라면 0을 반환해야 한다.
- 예약 날이 평일이라면 0을 반환해야 한다.
- 총주문 금액이 1만 원 이상이고 예약 날이 주말이라면 원하는 계산 결과와 정확히 일치해야 한다.
- 주문한 해당 카테고리 할인 계산 메서드
- 특별 할인 테스트
- 특별 할인 계산 메서드
- 총주문 금액 1만 원 미만이라면 0을 반환해야 한다.
- 별 있는 날이 아니라면 0을 반환해야 한다.
- 총주문 금액이 1만 원 이상이고 별 있는 날이라면 원하는 계산 결과와 정확히 일치해야 한다.
- 특별 할인 계산 메서드
- 이벤트 뱃지 테스트
- 이벤트 뱃지 계산 메서드
- 총혜택 금액이 2만 원 이상이라면 산타를 반환해야 한다.
- 총혜택 금액이 1만 원 이상 2만 원 미만이라면 트리를 반환해야 한다.
- 총혜택 금액이 5천 원 이상 1만 원 미만이라면 별을 반환해야 한다.
- 총혜택 금액이 5천 원 미만이라면 false를 반환해야 한다.
- 이벤트 뱃지 계산 메서드
- 상수 유틸 테스트
- 객체 동결 메서드 테스트
- 주어진 객체와 중첩된 객체 모두 불변해야 한다.
- 객체 동결 메서드 테스트
- 유틸 테스트
- 주문 메뉴 문자열 파싱 메서드 테스트
- 입력된 문자열을 배열로 반환해야 한다.
- 카테고리에 존재하는 메뉴 여부 검사 테스트
- 주어진 메뉴에 대해 올바른 카테고리를 찾아 반환해야 한다.
- 주문 메뉴 문자열 파싱 메서드 테스트
- 날짜 유효성 유틸 테스트
- 1 이상 31 이하의 숫자라면 정상적으로 작동해야 한다.
- 1 미만 31 초과의 숫자라면 에러를 반환해야 한다.
- 자연수가 아니라면 에러를 반환해야 한다.
- 주문 메뉴 유효성 유틸 테스트
- 존재하지 않는 메뉴를 입력했다면 에러를 반환해야 한다.
- 존재하는 메뉴를 입력했다면 정상적으로 작동해야 한다.
- 1 미만의 수량을 입력했다면 에러를 반환해야 한다.
- 1 이상의 수량을 입력했다면 정상적으로 작동해야 한다.
- 주문형식(메뉴-수량)이 맞지 않다면 에러를 반환해야 한다.
- 주문형식(메뉴-수량)이 맞다면 정상적으로 작동해야 한다.
- 중복된 메뉴를 입력했다면 에러를 반환해야 한다.
- 중복되지 않은 메뉴를 입력했다면 정상적으로 작동해야 한다.
- 음료만 주문했다면 에러를 반환해야 한다.
- 음료만 주문하지 않았다면 정상적으로 작동해야 한다.
- 수량이 20 초과라면 에러를 반환해야 한다.
- 수량이 20 이하라면 정상적으로 작동해야 한다.
- 유효성 유틸 테스트
- 올바른 날짜를 입력했다면 정상적으로 작동해야 한다.
- 올바르지 않은 날짜를 입력했다면 에러를 반환해야 한다.
- 올바른 주문 메뉴를 입력했다면 정상적으로 작동해야 한다.
- 올바르지 않은 주문 메뉴를 입력했다면 에러를 반환해야 한다.
🎄 테스트 결과
🎄 느낀점
객체지향 프로그래밍 적용하기
3주차까지만 해도 도메인이 아니라면 유틸 함수, UI 로직 등을 전부 함수형 프로그래밍 방식으로 작성했다. 함수형 프로그래밍을 적용한 이유는 ‘익숙하다’ 라는 점이 가장 컸다. 익숙하다는 것은 그만큼 사용하기 편리했다는 것인데 우선 함수형 프로그래밍이 주는 큰 장점은 동일한 인자가 전해지면 동일한 결과를 반환한다는 것이다. 이 장점을 통해 예측 가능한 코드를 작성할 수 있고 특히 하나의 모듈을 기준으로 독립적으로 진행하는 단위 테스트와 엄청난 시너지를 발휘할 수 있었다.
이번 과제에서 InputView 객체와 OutputView 객체가 주어졌다. 각각의 객체에는 예시 메서드들이 작성되어 있었다. 이 객체들을 보고 이번에는 객체지향 프로그래밍 방식으로 개발해야겠다는 생각이 들었다. 어쩌면 ‘이번엔 객체지향 프로그래밍 패러다임으로도 코드를 짜보자’ 라고 힌트를 준 거 같았다.
과제를 진행해보니 캡슐화라는 특징이 객체지향 프로그래밍을 하면서 가장 크게 다가온 이점이다. 캡슐화는 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하거나 조작할 수 있는 동작인 메서드를 하나로 묶는 것을 말한다. 이를 통해 정보 은닉도 가능하다는 장점도 있다. 처음에는 Promotion 이라는 클래스에 모든 혜택 로직들을 구현했다. 그치만 한 군데에서 할인 혜택 로직들을 전부 구현하니 가독성이 떨어졌다. 그래서 혜택 별로 관심사를 분리했고 각 혜택마다 계산하는 메서드를 작성하였다. 이렇게 분리하다 보니 각 객체마다 역할이 명확하게 정의되었고 코드의 결합도도 낮출 수 있었다.
클래스와 객체 리터럴 차이
이번 과제에 객체지향 프로그래밍 방식을 채택했다. 그러면 어떤 것을 클래스로 선언하고 어떤 것을 객체 리터럴로 선언해야할 지 고민이 되었다. 주어진 파일이 없었다면 혼란스러웠겠지만 InputView, OuputView 객체를 보고 힌트를 얻기도 했다.
클래스는 객체를 생성하기 위한 템플릿이다. 필드와 메서드를 통해 하나의 객체로 추상화 하여 인스턴트를 생성해서 객체를 실제화 하는 작업을 거친다. 상속을 구현하기에도 용이하다. 그치만 객체 리터럴은 간단한 객체나 유틸리티 함수를 정의할 때 유용한 방식이다. 별도의 인스턴스화 없이 객체를 생성하고 메서드를 호출이 가능하지만 상속을 구현할 순 없다.
따라서 무언가 생성해야 하는 틀이라면 클래스로 정의하고 하나의 고유한 존재라면 객체 리터럴 방식으로 구현해야겠다고 생각했다. 예를 들어, 주문 같은 경우에는 사용자에게 입력을 받아야만 생성될 수 있는 것이라 판단하여 클래스로 정의해서 관리하였고, 할인 프로모션(디데이할인, 평일 할인, 주말 할인 등) 같은 경우에는 굳이 프로퍼티를 생성하고 계산 값을 저장해서 반환하기 보다는 이미 고유한 존재들이라 생각해서 클래스로 정의할 필요가 없다고 느껴졌다. InputView와 OutputView도 그런 점에서 class 형식이 아니였다고 생각한다. 클래스 정의와 객체 리터럴 객체에 대해 깊은 고민과 적용을 해 본 특별한 경험이었다.
'Project' 카테고리의 다른 글
[회고록] 우아한 테크코스 6기 프리코스 3주차 회고 (1) | 2023.11.13 |
---|---|
[회고록] 우아한 테크코스 6기 프리코스 2주차 회고 (0) | 2023.11.02 |
[회고록] 우아한 테크코스 6기 프리코스 1주차 회고 (0) | 2023.10.27 |
[회고록] 2차 프로젝트를 마치며 (0) | 2023.06.29 |
[회고록] AI 챗봇 프로젝트 스터디 1차 회고록 (0) | 2023.06.03 |