2주차 하이
2주차 미션은 레이싱 게임입니다. 사용자에게 자동차 이름과 시도 횟수를 입력받고, 주어진 이름으로 생성된 자동차들을 시도 횟수만큼 랜덤으로 이동시켜 우승자를 정하는 식이네요!
미션 메일에서는 함수를 분리하고, 각 함수별 테스트를 작성하는 것에 익숙해질 것을 제안하고 있고, 그 외에도 1주차 공통 피드백에서 눈여겨볼만한 것들을 추려봤습니다.
- 이름을 통해 의도를 드러낸다 : 이름을 통해 변수, 함수, 클래스의 역할이 잘 드러나게끔 명명해보자!
- 축약하지 않는다 : 의도를 드러낼 수 있다면 이름이 길어져도 괜찮다! 축약은 혼란을 야기하며, 더 큰 문제를 숨기는 경향이 있다.
- linter와 Code Formatter의 기능을 활용한다 : eslint와 prettier를 적극적으로 활용하자
- 의미 없는 주석을 달지 않는다 : 주석으로 설명하기보다는 보기만 해도 의도가 드러나게 하고, 그게 힘들 경우에만 주석을 달자.
또한 제 개인적으로도 이번 주차의 목표를 정해보았습니다.
- 의존성 주입 원칙을 적용해보자 : 외부의 모듈이 필요한 경우 직접 생성하거나 불러오는 대신, 외부에서 생성한 후 주입하게끔 만들자.
- 과하게 분리하지 말자 : 재사용되지 않는 로직을 분리해서 밖으로 빼지 말자. 분리는 또 다른 의존을 만들어낼 수 있다.
- 한 함수가 하나의 기능만 하게 만들자 : SRP를 준수하자!
기능 목록 작성하기
과제 요구사항을 토대로 간단하게 기능 목록을 작성했습니다! 일단 두루뭉술하게 작성한 뒤, 구체적인 구현에 맞춰 수정해나가려고 합니다.
🤔 요구사항 리스트
구조 구상해보기
일단 이렇게 스케치를 해보았습니다
- RacingCar
- 이름, 결과 문자열, canMove, move 메서드
- canMove는 무작위 숫자를 뽑아서 4 이상인지 boolean 반환
- move는 canMove가 true이면 결과 문자열에 -를 더함
- RacingGame
- cars, winners, moveAllCars, setWinners
- 생성 시에 이름 배열을 받아서 각 배열의 요소로 RacingCar(item) 인스턴스 생성, 레이싱카가 들어있는 배열을 cars에 할당
- moveAllCars : this.#cars에 forEach걸어서 각 car의 move 메서드 호출, 각 car의 이동 결과를 join('\n')해서 반환 (출력용)
- setWinners : this.#cars에 reduce 걸어서 getMoveResult의 length 최대값을 구하고, 이 최대값과 일치하는 결과문자열 길이를 가진 차량을 this.#winners에 넣음
- RacingGameController
- #racingGame 필드, initiate, handleCarNamesInput, handleRoundsNumberInput
- handleCarNamesInput : 입력값을 콤마(,)기준으로 나눠서 배열로 만든 후에 유효성 검사 하고, 이를 파라미터로 넘겨 RacingGame 생성.
- handleRoundsNumberInput : 입력값을 parseInt해준 후 유효성 검사. for 반복문으로 roundsNumber만큼 이동과 출력을 반복한 뒤, racingGame의 setWinners로 우승자 설정
- initiate : inputView로 이름과 숫자 입력받음. 이름을 handle로 넘겨준 후에 outputView의 출력 함수로 '실행 결과' 출력하고, 숫자를 handle로 넘겨서 경기 진행시킴. racingGame의 getWinners로 우승자 가져와서 출력. 이후 프로세스 종료됨
- InputView
- readNamesInput, readRoundsNumberInput
- OutputView
- printResultHeader, printResult, printWinners
- printWinners : winners 배열을 받아서 ', '로 합치고, winnerAnnouncementHeader랑 합쳐서 출력
이 스케치를 기반으로 일단 구현해보았고, 테스트를 모두 통과하는 걸 확인했습니다! 구조적인 결함이 없는 걸 확인했으니, 다음은 예쁘게 리팩토링할 차례네요🧐