[2단계 - 웹 기반 로또 게임] 파라디 미션 제출합니다.#469
Conversation
파일: __tests__
파일: src/step1-App.js, src/step1-index.js
파일: src/services/LottoMachine.js, src/models/LottoResult.js, src/models/Purchase.js
파일: src/validates/CommonValidator.js, src/validates/LottoValidator.js, src/validates/PurchaseValidator.js
파일: src/controllers/MainController.js
파일: README.md
파일: __tests__/*
파일: src/controllers/MainController.js
파일: src/models/Purchase.js
파일: src/services/LottoMachine.js
파일: src/controllers/MainController.js, src/step1-App.js
파일: src/models/Lotto.js, src/views/InputView.js, src/views/OutputView.js, src/constants/config.js
파일: package.json, package-lock.json
파일: README.md
파일: __tests__/validation/LottoTest.js
파일: src/validates/LottoValidator.js
파일: src/models/LottoResult.js
파일: src/controllers/MainController.js
feat: 로또 프로그램 구현
JUDONGHYEOK
left a comment
There was a problem hiding this comment.
안녕하세요 파라디!! 2단계 미션도 너무너무 수고많으셨습니다. PR만 봐도 많은 고민을 하셨던게 느껴졌네요.
Controller가 흐름을 조율하고 View가 DOM을 전달하는 간단한 구조로 구현해주셨군요. 깔끔하고 좋습니다. 이렇게 간단한 애플리케이션을 구현하기에는 충분한 구조인 것 같아요. 각각의 역할에 대한 세밀한 피드백은 코멘트로 남겨두었으니 확인 부탁드려요! 현재 미션의 목적 중 하나가 웹 표준을 준수하는 마크업이라서 해당 부분에 대한 코멘트를 조금 남겨두었는데요. 요것도 코멘트로 확인해주시면 감사하겠습니다!!
Q&A
MainController, LottoView, LottoViewElements, LottoViewUtils로 역할을 나눈 기준이 적절한지 궁금합니다.
특히 View 전용 보조 함수/DOM 수집 파일까지 분리한 수준이 과하지 않은지 피드백 받고 싶습니다.
전체적인 구조는 그렇게 과하다고 생각은 들지 않았어요. 다만 LottoViewElement와 같은 경우에는 하나의 팩토리함수인데 현재 규모에서는 LottoView로도 충분히 표현가능하지 않나 라고 생각해요. 파일이 분리되면 DOM참조를 확인하려고 항상 두 파일을 왔다갔다 해야될 것 같아요.ㅎㅎ LottoViewElements가 LottoView없이 쓰일일이 없어서 현재 규모에서는 하나로 합쳐져도 괜찮을 것 같아요!
당첨 번호 입력값 정제 로직을 View 레벨(normalizeWinningInputValue)에서 처리한 선택이 적절한지 궁금합니다.
입력값 정제 로직이 view레벨에서 처리하는 것은 사용자가 물리적으로 입력할 수 있는 값의 범위를 제한한 UX적인 측면의 개선이라 이상하지 않다고 생각했어요. 이건 도메인 검증이랑은 다른 목적을 가진 검증이죠. 성능은 replace와 slice정도의 연산은 input 이벤트가 수천개요소 이지 않는이상 지금 수준에서는 고민하지 않아도 괜찮다고 생각해요
step2 테스트를 실제 DOM/jsdom까지 가지 않고, MainController와 LottoViewUtils 중심의 Jest 테스트로 제한한 판단이 적절한지 궁금합니다.
현재 프로젝트 규모에서 어느 정도 테스트 범위가 적정한지 피드백 받고 싶습니다.
이건 사실 테스트 커버리지의 문제일 것 같아요. 해당 모듈들을 꼼꼼하게 단위테스트한다고 해도 당연히 실제 DOM과의 연결동작에서의 검증은 이뤄지지 않겠죠. 모든 케이스를 jsdom으로 테스트할 필요는 없지만 핵심 사용자 시나리오 정도는 테스트로 작성해두면 셀렉터 오타나 이벤트 바인딩 누락 같은 결합단계에서 이뤄질수 있는 오류들을 검증할 수 있는 안정망이 될 수 있을 것 같아요. 하지만 요부분은 이번단계에서 필수는 아니라고 생각해서 파라디가 생각했을 때 정말 이 애플리케이션의 안정성을 위해 추가되어야한다고 느껴지고 시간이 좀 남는다고 생각하면 추가해보는 것도 좋은 경험이 될 것 같아요
브라우저 환경 대응을 위해 랜덤 로직을 공용 유틸(pickUniqueNumbersInRange)로 분리한 방식이 적절한지 궁금합니다.
공용 로직으로 올릴 범위와 step1/step2 전용 로직의 경계를 어떻게 잡는 게 좋은지 의견을 듣고 싶습니다.
이번미션의 가장 큰 목적중 하나가 UI와 도메인의 분리라고 생각해요. 현재 이 코드를 수정할 이유가 UI 변경때문인지 비즈니스 규칙 변경 때문인지를 생각하고 분리를 하면 되지 않을까 생각합니다. 그런 관점에서 랜덤로직을 공용 유틸로 분리한 것은 합리적인 판단이라고 생각합니다!
2단계도 너무 수고많으셨습니다! 남긴 코멘트 확인해주시고 언제든지 다시 리뷰요청주세요~~
| this.#lottoMachine = lottoMachine; | ||
| this.#view.renderLottoTickets(tickets, ticketCount); | ||
| } catch (error) { | ||
| alert(error.message); |
There was a problem hiding this comment.
alert는 브라우저 전용 API고 UI표현의 영역이에요 에러메세지를 보여주는 것에 대한 결정권을 Contoller가 가지면 역할을 벗어나게 됩니다!
There was a problem hiding this comment.
view에 showError()를 추가해서 view를 가져다 쓸 수 있도록 구조를 변경해보았습니다!
| export function getWinningFormValues(winningInputs) { | ||
| const numbers = Array.from(winningInputs, (input) => input.value); | ||
| const winningNumbers = numbers.slice(0, numbers.length - 1); | ||
| const bonusNumber = numbers[numbers.length - 1]; |
There was a problem hiding this comment.
마지막 요소가 보너스 번호라는 규칙이 DOM순서에 의해 암묵적으로 의존되는 것 같아요 만약 마크업 순서만 조금 바뀌어도 조용히 버그가 발생하게 되는데요. 보너스 번호도 별도의 selector로 가져오는 것은 어떠세요?
There was a problem hiding this comment.
좋은 것 같습니다!
보너스 번호에 id 부여해서 별도 selector로 명시적으로 가져오도록 바꿨습니다!
| return ""; | ||
| } | ||
|
|
||
| return parsedValue > 45 ? "45" : String(parsedValue); |
| @@ -0,0 +1,7 @@ | |||
| import MainController from "./js/controllers/MainController.js"; | |||
|
|
|||
| function App() { | |||
| <button id="show-result-button" type="submit">결과 확인하기</button> | ||
| </form> | ||
| </section> | ||
| <div id="result-modal-container" hidden> |
| <button id="modal-close">x</button> | ||
| <h2 id="modal-title">🏆 당첨 통계 🏆</h2> | ||
| <div id="result-text-container"> | ||
| <div id="result-table"> |
There was a problem hiding this comment.
table element 대신에 grid를 사용해주신 이유가 있으실까요?
| <div id="result-text-container"> | ||
| <div id="result-table"> | ||
| <div class="grid table-title"><span>일치 갯수</span><span>당첨금</span><span>당첨 갯수</span></div> | ||
| <div class="grid"><span>3개</span><span>5,000</span><span id="match-3-count"></span></div> |
There was a problem hiding this comment.
요런 값들도 유지보수 좋게 관리하려면 어떻게 할 수 있을까요?
| <h2 id="modal-title">🏆 당첨 통계 🏆</h2> | ||
| <div id="result-text-container"> | ||
| <div id="result-table"> | ||
| <div class="grid table-title"><span>일치 갯수</span><span>당첨금</span><span>당첨 갯수</span></div> |
|
|
||
| getRestartHandler()(); | ||
|
|
||
| expect(mockViewInstance.resetUI).toHaveBeenCalledTimes(1); |
There was a problem hiding this comment.
jest 사용이 미숙해서 그런 것 같은데, 혹시 상태 초기화 검증은 어떤 식으로 하면 좋을까요?
현재 수정은 mock 변수들을 초기화하고 재시작하여 몇 번 호출 됐는지 확인하는데 이 방식이 적절할까요??
| expect(normalizeWinningInputValue("a046")).toBe("4"); | ||
| expect(normalizeWinningInputValue("99")).toBe("45"); | ||
| expect(normalizeWinningInputValue("0")).toBe(""); | ||
| expect(normalizeWinningInputValue("")).toBe(""); |
There was a problem hiding this comment.
4가지 시나리오를 하나의 테스트로 검증하기 보다 test.each로 분리되면 실패시 어떤 입력에서 깨졌는지 더 명확해 질 것 같아요 경계값도 추가되면 좋을 것 같구요!
There was a problem hiding this comment.
의견 감사합니다! 전에도 항상 이런 여러 케이스(입출력이 정해져 있는 케이스)에 대해선 test.each를 사용했었는데 이 normalizeWinningInputValue 함수를 메인 함수가 아닌 유틸 정도의 계층으로 생각해서 크게 테스트에 신경을 안 썼던 감이 없지 않아 있네요.. jest 사용이 아직도 미숙한 것 같습니다 ㅎㅎ 수정했습니다!
학습 목표
이번 미션을 통해 다음과 같은 학습 경험들을 쌓는 것을 목표로 합니다.
제출 전 체크 리스트
리뷰 요청 & 논의하고 싶은 내용
1) 이번 단계에서 가장 많이 고민했던 문제와 해결 과정에서 배운 점
1. step1 로직 재사용
2. 분리 관점
3. ux 관점
4. css 관련
css에선 피그마를 참고해서 css/base/global.css에서 전역 스타일 설정값으로서 모두 변수로 만들어 사용했습니다.
예전부터 순수 css 파일을 많이 다룰 때 속성 순서를 통일하는 습관이 있었습니다. 개인적으론 요소의 위치와 크기를 알 수 있는 속성들(display, position, width/height, margin/padding, 정렬)을 먼저 상단에 작성하고, 부가적인 것들을 하단에 작성하는 것이 가독성 면에서 편했던 것 같습니다. 따라서 css 속성 작성 시 아래와 같이 순서를 중요시했습니다.
css 순서
5. 테스트 관련
2) 이번 리뷰를 통해 논의하고 싶은 부분
MainController,LottoView,LottoViewElements,LottoViewUtils로 역할을 나눈 기준이 적절한지 궁금합니다.특히 View 전용 보조 함수/DOM 수집 파일까지 분리한 수준이 과하지 않은지 피드백 받고 싶습니다.
당첨 번호 입력값 정제 로직을 View 레벨(
normalizeWinningInputValue)에서 처리한 선택이 적절한지 궁금합니다.입력 편의성과 도메인 검증 책임을 어디까지 분리하는 게 좋은지 의견을 듣고 싶습니다. 프로젝트가 커지면 최적화 측면에서 버벅일 수도 있겠다는 생각이 들었습니다.
step2테스트를 실제 DOM/jsdom까지 가지 않고,MainController와LottoViewUtils중심의 Jest 테스트로 제한한 판단이 적절한지 궁금합니다.현재 프로젝트 규모에서 어느 정도 테스트 범위가 적정한지 피드백 받고 싶습니다.
브라우저 환경 대응을 위해 랜덤 로직을 공용 유틸(
pickUniqueNumbersInRange)로 분리한 방식이 적절한지 궁금합니다.공용 로직으로 올릴 범위와
step1/step2전용 로직의 경계를 어떻게 잡는 게 좋은지 의견을 듣고 싶습니다.✅ 리뷰어 체크 포인트
1단계
2단계