[2단계 - 웹 기반 로또 게임] 이스타 미션 제출합니다.#473
[2단계 - 웹 기반 로또 게임] 이스타 미션 제출합니다.#473Eastar-DS wants to merge 102 commits intowoowacourse:eastar-dsfrom
Conversation
eastroots92
left a comment
There was a problem hiding this comment.
안녕하세요 이스타 고생 많으셨어요.
자잘자잘한 피드백 보다 큰 맥락에서 고민해보시면 좋을 내용이 있어 코멘트 남겨 두었어요!
이번 리뷰를 통해 논의하고 싶은 부분
현재 구현한 UI는 반응형이 아니라 크기가 고정되어있는데요, 이왕 이번 미션을 통해 html과 css에 대해 공부를 시작한겸 반응형으로는 어떻게 만들어야 할지도 학습해두는게 좋을까요?
저는 이번 과제에선 불필요하다 생각해요. 반응형 웹을 연습하기엔 너무 가벼운 기능이기도 하고, 이번 과제의 목표는 아니였다고 생각하기 때문이에요.
제가 생각하는 이번 과제의 목표는 UI로직과 도메인 로직을 잘 나누는 것, 도메인 로직을 어떻게 하면 콘솔 UI와 웹 UI를 둘다 호환 할 수 있는 설계를 만들 수 있을까? 라고 생각해요.
그런 의미에서 반응형 웹을 고민하기보단 이번 목표 관점에서 한번 더 고민해보시면 좋겠어요.
(단 반응형 웹은 많은 연습이 필요한 것은 맞아요. 틈틈히 연습하시는 것을 추천해요!)
View와 Controller를 어떻게 분리해야할지, 분리를 할때 고려해야할 점
step1에서 만든 코드의 흐름을 그대로 따라가도 된다고 생각해요. 도메인 로직(Lotto, WinningLotto, ScoreBoard)은 동일하고 View 영역만 콘솔 -> 웹으로 바뀌는 것이기 때문이에요.
위에 언급 한 것 처럼 "관심사를 잘 분리하는 것"이 이번 과제의 목표였다고 생각해요.
getElementById가 컨트롤러에 있어도 되는가? 여부는 상황에 따라 다른 것 같아요. 컨트롤러의 역할이 무엇이냐에 따라 다르기 때문이에요. 다만 지금은 의도적으로 관심사를 분리하는 것 이기 때문에.
View(UI 로직) - Controller(연결다리) - Model(로또 로직) 를 의도적으로 분리해보시면 좋겠어요.
html, css파일을 하나만 사용해서 모두 작성했는데요, UI를 컴포넌트 단위로 만드는 것이 더 권장되는 방식인지 궁금합니다.
이 부분은 제가 직접 답변하기보다 SPA와 번들링 관련하여 공부해보시는 것을 추천해요.
더 엄밀히는 웹 렌더링의 변천사를 살펴보시며 왜 이렇게 바뀌었을까? 를 고민해보시면 좋겠어요.
지금 이스타가 고민하신 것 처럼 처음에는 단순히 하나의 html, css 파일로 시작했을 텐데 점점 규모가 커지고 요구사항이 많아지며 지금의 React와 같은 방식이 나왔기 때문이에요.
(다만 이게 무조건 React 같은 방식이 좋다는 것은 아니고 상황에 따라 적절한 선택이 필요해요)
step1처럼 CLI에서 로또게임을 진행하게 되는 경우와, step2처럼 웹브라우저 환경에서 로또게임을 진행하게 되는경우 View쪽을 구현할때 고려해야할 점이 많이 다를까요?
변하지 않는 것과 변하는 것을 분리해서 생각해보시면 좋아요.
변하지 않는 것은 로또 로직이고 변하는 것은 입출력이에요.
콘솔은 입력 > 처리 > 출력 이 명확하게 순차적으로 진행되지만 웹은 이게 동시다발로 동작하기에 이벤트 기반으로 동작해요. 이 특성을 이해해 보시면 좋겠어요.
고생 많으셨습니다.
| @@ -1,16 +1,129 @@ | |||
| <!DOCTYPE html> | |||
| <!doctype html> | |||
There was a problem hiding this comment.
에러 내용을 구체적으로 알 수 있도록 상수를 추가하고 유효성을 검사하는 부분에서 해당 메세지를 사용하도록 수정했습니다.
There was a problem hiding this comment.
질문!
등수 밖 로또에서 undefined 키가 생기는데 의도한 내용인지 궁금해요.
There was a problem hiding this comment.
undefined 키가 생기는것은 의도하지 않은 내용이였습니다!
step1에서 undefined가 생기는 것은 알고 있었지만 문제없이 로또게임이 진행되어 별 생각없이 넘어갔었는데요(ㅎㅎ...), 리뷰를 받아보니 양심이 찔리네요ㅠㅠ
코드를 수정하는 방법으로 두가지가 생각났었는데요, 하나는 스코어보드의 getRank 메소드에서 1~5등이 아니면 null을 반환하는 방법, 두번째는 constant에 당첨 이외의 등수를 추가하고 getRank 메소드에서 해당 값을 반환하는 방법이였습니다.
저는 두번째 방법을 택했는데요, 혹여 로또게임 결과를 반환하는 과정에서 당첨되지 않은 로또의 수도 출력해야할 수 있을 것 같아서 "NONE"으로 미리 추가해두는게 좋다고 생각했습니다.
NONE의 MATCH_COUNT는 일단 0으로 설정해두었는데요, NONE은 getRank에서 마지막줄에 기본값으로 사용할 상수이기 때문입니다. 이부분에서 질문이 있는데요, 0으로 설정해두면 아무번호도 일치하지 않는경우로 착각될수가 있고, -1같은 값으로 설정해두면 실제 불가능한 상태인 -1개를 입력해두어야해서 모두 약간의 부자연스러움이 느껴졌는데요, 혹시 두번째 방법에서 더 괜찮은 방법이 있는지 궁금합니다. 혹은 제가 택한 두번째방법보다 첫번째 방법이 선호되는 방법인지도 궁금합니다!
src/step2-index.js
Outdated
| document.getElementById("rank-3rd").textContent = `${allRankCount.THIRD}개`; | ||
| document.getElementById("rank-2nd").textContent = `${allRankCount.SECOND}개`; | ||
| document.getElementById("rank-1st").textContent = `${allRankCount.FIRST}개`; | ||
| profitRate.innerHTML = `당신의 총 수익률은 <strong>${rate}</strong>%입니다.`; |
There was a problem hiding this comment.
p3; innerHTML 사용은 XSS 위험이 있어요
지금은 rate가 toFixed(1)로 생성된 숫자 문자열이라 안전하지만, innerHTML은 습관적으로 쓰면 XSS취약점으로 이어질 수 있어요. 가능하면 textContent를 쓰거나, HTML 구조가 필요하다면 index.html에 태그를 미리 만들어두고 그 안의 textContent만 교체하는 방식이 더 안전해요.
There was a problem hiding this comment.
리뷰해주신 내용 덕분에 XSS 위험이라는 것을 처음 알게 되었습니다. 감사합니다!
innerHTML에 변수를 넣으면 그 변수에 HTML 코드가 들어있을 경우 그대로 실행되는 문제라고 이해했습니다.
리뷰해주신 수익률 출력쪽의 코드는 말씀해주신대로 index.html 파일의 태그에 id를 추가하고 해당 태그안의 텍스트만 교체하는 것으로 수정했습니다!
추가적으로 innerHTML이 있지만 빈 문자열이라 XSS 위험은 없는 부분인 lottoList.innerHTML = ""; 도 습관적으로 innerHTML을 사용하는 것을 막기 위해 while문을 이용해서 대체해보았습니다.
| @@ -2,3 +2,164 @@ | |||
| * step 2의 시작점이 되는 파일입니다. | |||
There was a problem hiding this comment.
P1;
step1에 비해 step2는 역할분리가 덜 되어있는 것 같아요.
큰 맥락에서 로또나 스코어보드 로직을 동일하게 사용하는 것은 맞으나 Input, Output 역할이 분리되어 있지 않고, 혼재되어있는 것 같아요.
웹에서 만약 로직과 UI의 input, output을 나누어 관리한다면 어떻게 해볼 수 있을까요?
There was a problem hiding this comment.
일단은 step1과 가능한 유사하게 로직과 UI를 분리하려고 노력해보았습니다.
step1의 InputView, OutputView와 유사하게
step2에서는 InputViewWeb, OutputViewWeb로 분리하였습니다.
컨트롤러에서는 이벤트리스너를 추가해야하는 html 태그만 document.getElementById()로 불러와서 사용했습니다.


학습 목표
이번 미션을 통해 다음과 같은 학습 경험들을 쌓는 것을 목표로 합니다.
제출 전 체크 리스트
리뷰 요청 & 논의하고 싶은 내용
1) 이번 단계에서 가장 많이 고민했던 문제와 해결 과정에서 배운 점
AI를 이용해서 필요한 부분을 먼저 학습하기로 결정했는데요, 제일 먼저 미션에서 쓰게될 html 태그들을 훑어보고, css를 어떻게 적용시키는건지 찾아보았습니다. 태그, 클래스, 아이디로 css를 적용시킬 수 있다는 것을 확인했고, 가능한 css는 클래스에 적용시키고 js쪽에서는 id를 이용하려고 했습니다.
2) 이번 리뷰를 통해 논의하고 싶은 부분
✅ 리뷰어 체크 포인트
1단계
2단계