로또 번호의 숫자 범위는 1~45까지이다.
1개의 로또를 발행할 때 중복되지 않는 6개의 숫자를 뽑는다.
당첨 번호 추첨 시 중복되지 않는 숫자 6개와 보너스 번호 1개를 뽑는다.
당첨은 1등부터 5등까지 있다. 당첨 기준과 금액은 아래와 같다.
1등: 6개 번호 일치 / 2,000,000,000원
2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원
3등: 5개 번호 일치 / 1,500,000원
4등: 4개 번호 일치 / 50,000원
5등: 3개 번호 일치 / 5,000원
로또 구입 금액을 입력하면 구입 금액에 해당하는 만큼 로또를 발행해야 한다.
로또 1장의 가격은 1,000원이다.
당첨 번호와 보너스 번호를 입력받는다.
사용자가 구매한 로또 번호와 당첨 번호를 비교하여 당첨 내역 및 수익률을 출력하고 로또 게임을 종료한다.
사용자가 잘못된 값을 입력할 경우 "[ERROR]"로 시작하는 메시지와 함께 Error를 발생시킨 후 애플리케이션은 종료되어야 한다.
구입금액을 입력해 주세요.
8000
8개를 구매했습니다.
[8, 21, 23, 41, 42, 43]
[3, 5, 11, 16, 32, 38]
[7, 11, 16, 35, 36, 44]
[1, 8, 11, 31, 41, 42]
[13, 14, 16, 38, 42, 45]
[7, 11, 30, 40, 42, 43]
[2, 13, 22, 32, 38, 45]
[1, 3, 5, 14, 22, 45]
당첨 번호를 입력해 주세요.
1,2,3,4,5,6
보너스 번호를 입력해 주세요.
7
당첨 통계
---
3개 일치 (5,000원) - 1개
4개 일치 (50,000원) - 0개
5개 일치 (1,500,000원) - 0개
5개 일치, 보너스 볼 일치 (30,000,000원) - 0개
6개 일치 (2,000,000,000원) - 0개
총 수익률은 62.5%입니다.
READ.md를 상세히 작성한다
지금까지 리드미를 작성할 때 프로그램의 순차적인 흐름에 따라 기능을 나열하는 식으로 작성해왔다. 공통 피드백을 참고하여 3주차 미션에서는 클래스 단위로 어떤 역할을 하는지 위주로 작성했다.
한 메서드가 한 가지 기능만 담당하게 한다
2주차 미션까지 함수형으로 구현해왔는데 클래스의 메서드와 함수가 거의 같은 기능을 하는 것 같았다. 3주차 미션부터는 클래스로 구현하기로 했다. 클래스에서 여러 가지 메서드를 구현하다보니 코드가 계속 길어졌다.
그래서 메서드 분리 전에 기능부터 분리했다. 메서드를 실행하는 코드가 길어지면 공통 기능단위로 여러 가지 메서드를 묶어 하나의 메서드로 만드는 식으로 코드의 길이를 줄였다.
#validate(number, winningNumber) {
NumberValidator.validateIsEmpty(number);
NumberValidator.validateIsOnlyDigits(number);
const parsedNumber = parseInt(number, 10);
LottoNumberValidator.validateLottoNumberRange(parsedNumber);
this.#validateBonusInWinningNumber(parsedNumber, winningNumber);
}
validate
메서드는 빈 문자열, 숫자여부, 1~45사이인지 여부, 보너스번호와 중복여부를 검사한다. 추가로 도메인, 입출력 또한 기능 단위를 나누어 큰 단위의 메서드안에 작은 단위의 메서드들로 구성했다.
테스트를 작성하는 이유는?
2주차까지는 기능 구현에 대한 테스트만 작성했다. 테스트 코드를 짜는 게 처음이기도 했고, 기본적으로 주어진 테스트만 통과하는 선에서 다른 테스트를 추가하는 정도였다. 2주차 코드리뷰를 하면서 내가 짰던 테스트는 오로지 "구현"을 위한 테스트라는 것을 깨달았다.
좋은 테스트는 실제 코드를 구현하기 직전에 구현하고, 독립적이며 의존적이지 않아야 한다는 것을 참고하여 이번 미션에서는 메서드 단위로 테스트를 작성했다. 독립적으로 동작하게 하기 위해 값을 넘기는 행위는 하지 않았고, 임시 데이터를 넣어 메서드를 테스트했다. 이렇게 하니 어디서 오류가 났는지 바로 알 수 있었고, 다시 고치는데까지 시간이 매우 줄어들었다.
그럼에도 TDD는 너무 어려웠다. 구현 직전에 테스트를 짜는건데 나는 구현->테스트를 작성하는 식으로 했다. 미리 테스트를 짜는 게 익숙치 않았고 동작을 예상함에 있어서 추상적이라고 느꼈다. 그래서 TDD는 하지 않되 단위 테스트를 열심히 작성하기로 했다.
내가 작성한 테스트
메서드당 15줄이 넘어가지 않도록 하는게 프로그래밍 요구사항이었는데 하나의 파일에서 15줄이 넘어가서 완벽하게 요구 사항을 지키지 못한게 아쉬웠다.
static
이나 private
메서드를 어떤 경우에 써야 하는지 헷갈려서 다음에는 각각 어떤 상황에서 쓸 지 확실하게 기준을 정해야겠다는 생각이 들었다.
다행히 예제 테스트 결과가 만족이 되었고 회고를 적고 제출했다.
3주동안 프리코스를 하다보니 언제부터 월요일 오후 3시가 기다려진다. 새로운 미션은 무엇일지 어떤 요구사항이 추가되었을지 궁금하다. 이제 마지막 미션인데 끝까지 열심히 해야겠다.