
어느덧 프리코스가 벌써 3주차 과제가 끝나고 마지막 주차만 남겨두고 있는 상황이군요 ! 개발하는 토마토는 지금 거의 절인 토마토가 된 수준이랍니다.. 이번 과제는 특히 말도 많고 탈도 많았던 (아니 제 기준 탈이 많았습니다!) 회차인 만큼 코드리뷰도 많이 기대도되네요!
이번 주차 과제는 로또 입니다! (약간 짜고치기 같긴하지만,,) 로또 구입금액을 1000원 단위로 입력하고, 구입 금액 만큼 로또 번호를 받은 후에 사용자가 입력한 당첨 번호 및 보너스 번호와 비교하여 수상 금액을 결정하는 방식입니다! 원래 기존 로또라면 사용자가 번호를 택하고 생성기가 만들어준 번호와 비교하는 시스템이라면 약간은 반대라서 기능 요구사항을 읽으면서 이게 맞나? 라는 의심을 한 두번 했던게 아니랍니다,,, 🥹

📂 폴더 구조
src
┣ constants
┃ ┣ ErrorMessage.js
┃ ┣ IOMessage.js
┃ ┗ MagicNumber.js
┣ service
┃ ┣ InputService.js
┃ ┗ OutputService.js
┣ util
┃ ┣ calculators
┃ ┃ ┣ calProfitRate.js
┃ ┃ ┗ calTotalPrize.js
┃ ┣ formatters
┃ ┃ ┣ formatLottoNums.js
┃ ┃ ┣ formatNum.js
┃ ┃ ┗ trimNums.js
┃ ┣ validators
┃ ┃ ┣ InputValidator.js
┃ ┃ ┣ LottoListValidator.js
┃ ┃ ┗ LottoNumValidator.js
┃ ┣ LottoGenerator.js
┃ ┣ countMatchedNums.js
┃ ┗ matchLottoNums.js
┣ App.js
┣ BonusNum.js
┣ Lotto.js
┣ LottoPrice.js
┗ index.js
📂 constants -> 에러메시지 및 매직 넘버, 입출력시 메시지 상수로 빼기 (1,2주차 코드리뷰 반영)
📂 service -> 입력 및 출력에 대한 함수 구현
📂 util
> 📂 calculators : 계산 함수
> 📂 formatters : 숫자 및 배열 포매팅 함수
> 📂 validators : 유효성 검사 클래스
LottoGenerator : 로또 번호 생성기
countMatchedNums: 일치 갯수 바탕으로 각 항목별 수상 판단
matchLottoNums : 로또 번호 일치 갯수 판단
BonusNum, Lotto, LottoPrice : 보너스 번호, 로또, 로또 구입 금액에 대한 클래스
이번 주차 신경썼던 점🤔
1. 함수를 최대한 작게 쪼개려고 노력했어요!
2. 중복 테스트를 줄이고 함수 단위 테스트를 해보려고 노력했어요!
3. 입출력 관련 메시지 등 필요한 부분은 최대한 상수로 지정하였습니다!
유효성 검사에 대한 많은 생각🤔
이 부분은 많은 분들께서 PR 메시지로도 남겨주셨고, 저 역시 개발하면서 정말 고민을 많이 했던 부분인데요! 예외처리와도 직결되는 문제이다 보니 중요하지 않다고 할 수가 없는 부분인데요, 제 생각은 개인적으로 다음과 같습니다.
"공통 유효성 검사는 하나로 두되 각 도메인 별로 특수한 유효성 검사는 도메인 별로 둔다."
물론 무조건 유효성 검사를 각 도메인에서 하는 방법도 있습니다만, 저는 개인적으로 특히 이번 주차 미션에서 유효성을 판단하는 조건이 꽤 중복된다고 느꼈습니다. 그렇다 보니 빈값을 입력하는 경우, 숫자가 입력되어야 하는데 문자열이 입력되는 경우 등 공통 유효성 검사를 (InputValidator) 에 두고 각 클래스에서 import 해서 사용하였습니다. 또한, 각 도메인 별로 특수하게 적용되는 조건(아래와 같이 로또 금액에 대한 부분) 은 클래스 내부에 두었습니다!

제가 택한 방법도 역시 단점은 있습니다.
1) 유효성 검사를 해야될 대상이 많아질 경우 공통 유효성 조건이 뭔지 판단하기 어려울 수 있다는 점,
2) 공통 유효성 검사를 택했던 클래스 들에서 일부 조건이 바뀔 경우 결국 다시 도메인 내로 들어가야 한다는 점
우선 그렇지만 제가 택한 이유는 이렇다 ! 라는 걸 남기고 싶었습니다 ㅎㅎ
이번 주차 궁금했던 점 & 깨달았던 점🤔
1. 왜 클래스에서 static 메서드를 사용하는 걸까?
우선 간단히 말하자면, 인스턴스 생성 없이도 호출해서 사용할 수 있기 때문입니다. 특정 메서드가 클래스의 인스턴스 상태나 속성에 전혀 의존하지 않는다면 인스턴스를 생성하는 것은 불필요한 작업이죠 :( 메모리를 절약할 수 있을 뿐만 아니라 코드도 간결해진다는 장점이 있습니다!
😳 static 메서드(정적 메서드) 가 뭔지 알고 싶다구요? 인스턴스 생성 없이 호출하는게 어떤 장점이 있냐구요?
-> 이건 다음 글에서 확인해보시죠 !
2. Export문에 대해 알아보자
무지성으로 쓰던 'export default'.. 지금까지 왜 쓰는지도 제대로 모르고 써왔는데 드디어 의미를 알았습니다
named export : 여러 개의 모듈을 내보낼 수 있고, 중괄호를 사용해야 모듈을 가져올 수 있습니다
default export : 해당 모듈엔 개체가 하나임을 나타내고, 중괄호 없이 모듈을 가져올 수 있습니다

named export : 기능 단위로 모듈을 묶어 사용할 때 유리, 하지만 이름을 정확하게 가져와야 함
default export : 가져올 때 자유롭게 이름을 가져올 수 있음, 코드 작성 의도가 명확해짐
3. 상수에 메시지들 정의하는데 특정 값이 업데이트 되어야 하는 경우가 있다면?
PROFIT_RATE 의 경우 수익률이 매번 다르게 계산되므로 값이 업데이트가 될 필요가 있었는데 이경우 상수 값에 함수형 처럼 정의를 하면 됩니다 ! (사용법은 아래와 같다)
export const IOMessage = Object.freeze({
PRICE_INPUT: '구입금액을 입력해 주세요.',
LOTTO_INPUT: '당첨 번호를 입력해 주세요.',
BONUS_NUM_INPUT: '보너스 번호를 입력해 주세요.',
WIN_STATISTICS: '당첨 통계\n---',
PROFIT_RATE: (rate) => `총 수익률은 ${rate}%입니다.`,
});
이번 주차 스스로에게 아쉬웠던 점🤔
TDD 를 하겠다고 마음 먹고 코드를 짜다 보니 기능 개발로 넘어가서 뭔가 모르게 뒤죽박죽 개발한 느낌이었습니다.. 그러다 보니 시간도 배로 걸린 느낌? 최종 코테를 보게 된다면 사실 정해진 시간 안에 코드를 짜야 하기 때문에 빠른 사고와 결정으로 진행해야 하는데 각 과제마자 일주일 이라는 시간이 있으니 알게 모르게 늘어지는 느낌이 들었습니다🥲 다른 것들과 병행도 하고 있다 보니 아 내가 진짜 몰입하고 있나? 라는 의문도 좀 들기도 하고,, 여러 고민이 많았던 한 주 였던 것 같아요 ! 그래도 한 주만 더 하면 프리코스가 완료된다고 하니 시원하면서도 섭섭하지만, 많은 것들을 배우고 있는 것 같아 너무 좋은 기회 인것 같습니다!
다음 주 목표 🔥
✅ 시간 정해놓고 그 안에 구현해 보기
✅ 공통, 코드리뷰 모두 놓치지 않고 피드백 반영하기
'우아한 테크코스 > 우당탕탕 우테코 프리코스' 카테고리의 다른 글
| 우당탕탕 우테코 7기 최종 코테 후기 🔥 (3) | 2024.12.15 |
|---|---|
| 우당탕탕 우테코 7기 4주차 프리코스 회고 🔥 (8) | 2024.11.15 |
| 우당탕탕 우테코 7기 2주차 프리코스 회고 🔥 (3) | 2024.10.29 |
| 우당탕탕 우테코 7기 1주차 프리코스 회고 🔥 (6) | 2024.10.22 |