☘️ 시작하기 앞서...
📚 2주 차 짧은 후기
무사히 2주차까지 마무리하였다.
2주 차 때에는 1주 차와 달리 코드 리뷰를 진행해 보았고 다른 사람들의 코드를 보면서 어디가 좋은지 별로인지 확인할 수 있게 되어 성장하는 기분이었다!!
📚 2주차 공통 피드백
2주 차 공통 피드백을 확인하였고 이번 3주 차에는 어떤 걸 신경 쓰면서 구현할지 생각해 봤다.
✏️ README.md 작성
README.md를 상세히 작성한다
지금까지 README.md에 구현할 기능에 대해서만 작성했는데,
피드백과 다른 사람들의 코드를 보면서 구현할 기능 이외에도
해당 프로젝트가 어떤 프로젝트이고, 어떤 것을 요구하지는 명시해야겠다는 생각을 했다.
✏️ 하드코딩 X
값을 하드 코딩하지 않는다
이건 내가 코드리뷰를 통해 피드백받은 것과 같은 내용이다.
문자열, 숫자 등을 코드에 그대로 쓰지 말고, 상수를 만들라는 것이다.
그래서 이번에는 문자열과 숫자를 상수를 만들어 활용할 것이다.
✏️ 구현 순서
구현 순서도 코딩 컨벤션이다
구현 순서는 필드 -> 생성자 -> 메서드 순으로 작성하라고 했다.
✏️ 함수 한 가지 기능
한 함수가 한 가지 기능만 담당하게 한다
하나의 함수에서 여러 기능을 수행하지 말고 한 가지 기능을 수행해야 한다.
✏️ 목표를 중심으로 학습
이번에는 목표를 중심으로 학습하라 하였고 목표는 아래와 같다.
- 클래스(객체)를 분리하는 연습
- 도메인 로직에 대한 단위 테스트를 작성하는 연습
✏️ 결론
이 외에도 여러 피드백이 있었다.
피드백을 반영하여 지난주 보다 더 좋아진 코드를 작성하고 싶다!
☘️ git 프로젝트 관리
프로젝트 fork를 해서 나의 깃허브 저장소에 프로젝트를 가져오고,
git clone을 하여 내 로컬에서 코드를 작성할 수 있게 한다.
(git 프로젝트 관리에 대한 자세한 내용은 1주 차 후기 게시물에 있다.)
그리고 1, 2주 차 때 브랜치의 이름을 모두 task2/미션이름 이런 식으로 했었는데,
다른 사람들이 한 것을 보니깐 대부분 본인 이름으로 브랜치 이름을 지어 사용하였다.
그래서 나도 이번에는 내 이름으로 브랜치 이름을 지었다.
☘️ eslint & prettier 설정
이번에도 지난 2주 차 때와 동일하게 eslint & prettier 를 사용할 것이다.
그전에 프로젝트를 할 때 eslint & prettier를 사용한 적이 있어 익숙했지만, 역시 eslint랑 prettier는 좋다👍
자동으로 코드 스타일을 맞춰주고 좋지 부분도 알려주어 코드를 어떻게 작성하고 수정해야 될지 알게 된다.
(eslint & prettier 설정에 대한 자세한 내용은 2주 차 후기 게시물에 있다.)
지난주에 적용했던 것과 똑같이 설정하였다.
그런데 추가적으로 이번 미션 요구사항에 이런 내용이 있었다.
함수(또는 메서드)의 길이가 15라인을 넘어가지 않도록 구현한다.
그래서 .eslintrc 파일에 함수의 길이가 15라인을 넘을 경우 에러라고 표시되도록 수정하였다.
"rules": {
"max-depth": ["error", 2],
"max-lines-per-function": ["error", { "max": 15 }]
}
☘️ 프로젝트 기능 문서 작성
역시나 첫 번째는 프로젝트 기능 문서 작성하는 것이다.
작성하기 전에 유의해야 될 점이 있어 이를 참고하여 작성하기로 했다.
어떤 프로젝트인지, 구현할 기능 목록
📚 어떤 프로젝트인지
먼저 해당 프로젝트가 어떤 것인지, 어떻게 진행되는지 문서를 작성하였다.
해당 프로젝트가 어떤 프로젝트인지 문서를 작성했으므로, 깃에 올려준다.
📚 구현할 기능 목록
어떤 프로젝트인지 문서로 작성하면서 기능에 대해 보다 쉽고 빠르게 파악하였고,
이를 바탕으로 어떤 것을 어떻게 구현할지 기능 목록 문서를 작성하였다.
구현할 기능 목록 문서도 작성했으므로, 깃에 올렸다.
☘️ 미션 구현하기
다른 사람들의 코드를 보니깐 MVC 패턴으로 구현한 것이 많아 보였다.
다행히도 MVC 패턴은 옛날에 Spring을 공부했었을 때 적용을 해 본 경험이 있어 크게 생소하거나 어렵진 않을 것 같다!
MVC(Model - View - Controller) 패턴
Model: 데이터와 비즈니스 로직을 관리
View: 레이아웃과 화면을 처리
Controller: 모델과 뷰로 명령을 전달
📚 디렉토리 구조
MVC 패턴으로 구현하기 위해 디렉토리를 새로 추가해서 만들어야 되는데 나는 이렇게 구분하기로 했다.
- model 폴더: 내부 비지니스 로직을 처리를 위한 객체
- view 폴더: input, output
- controller 폴더: 게임의 전체적인 로직 관리
- utils 폴더: 메시지, 상수
기존에 있던 Lotte.js 는 model 폴더와 성격이 맞아 해당 폴더로 이동시켜 줬다.
그러면 이제 본격적으로 미션을 구현해 볼 것이다!
📚 로또 구입 금액 입력 받기
처음 구현할 것은 로또 구입 금액에 관련된 것이다.
먼저 전체적인 게임 로직을 관리하는 LottoGameController.js, 로또 구매 객체에 관한 Purchase.js 를,
그리고 입력받는 InputView.js, 출력하는 OutputView.js, 메시지 관련 내용을 상수 처리한 message.js 를 생성하였다.
LottoGameController.js 에서 로또 구매 금액 입력받는 함수와 로또 구매 금액을 객체에 저장하는 함수를 만들었다.
import Input from "../view/InputView";
import Output from "../view/OutputView";
import Purchase from "../model/Purchase";
class LottoGame {
// 로또 게임 플레이
async lottoGamePlay() {
await this.getLottoPurchaseAmount();
}
// 로또 구매 금액 입력 받기
async getLottoPurchaseAmount() {
const purchaseAmount = await new Input().readLottoPurchaseAmountInput();
const purchase = this.setLottoPurchaseAmount(purchaseAmount);
await new Output().printResult(purchase.getAmount());
}
// 로또 구매 금액 저장
setLottoPurchaseAmount(purchaseAmount) {
const purchase = new Purchase(Number(purchaseAmount));
return purchase;
}
}
export default LottoGame;
Purchase.js 에 있는 객체에 로또 금액을 저장하고 여기서 유효성 검사를 하면 된다.
class Purchase {
#amount;
constructor(amount) {
this.#validate(amount);
this.#amount = amount;
}
#validate(amount) {
// 예외 아직
}
getAmount() {
return this.#amount;
}
}
export default Purchase;
✏️ App.js 에서 객체 생성
그런데 하위 함수에 다른 클래스의 함수를 호출할 때, 해당 클래스에 대한 객체를 생성하는 게 코드상으로 별로인 것 같다.
ex)
const purchaseAmount = await new Input().readLottoPurchaseAmountInput();
...
await new Output().printResult(purchase.getAmount());
그래서 미리 App.js에서 호출할 클래스에 대한 객체를 먼저 생성하는 게 더 좋을 것 같아서 그렇게 수정해 보았다!!
+) 그전에 Purchase 객체를 만들어 데이터를 넣는 것을 따로 CreateModel.js 파일을 만들어 생성하였다.
import Purchase from "./Purchase";
class CreateModel {
createPurchaseModel(amount) {
return new Purchase(amount);
}
}
export default CreateModel;
이제 본격적으로 App.js 에서 미리 다른 클래스 객체를 생성하여, LottoGameController.js 에 생성된 객체를 넣어줄 것이다.
class App {
async play() {
const createModel = new CreateModel();
const purchase = new Purchase();
const input = new Input();
const output = new Output();
const lottoGame = new LottoGame(createModel, purchase, input, output);
await lottoGame.lottoGamePlay();
}
}
그러면 LottoGameController.js 에는 App.js 에서 생성된 객체를 생성자로 받게 되어 this.{이름} 이렇게 하면 해당 클래스의 함수를 사용할 수 있게 된다.
class LottoGame {
constructor(createModel, purchase, input, output) {
this.CreateModel = createModel;
this.Purchase = purchase;
this.Input = input;
this.Output = output;
}
// 로또 게임
async lottoGamePlay() {
const purchase = await this.getLottoPurchaseAmount();
}
// 로또 구매 금액 입력 받기
async getLottoPurchaseAmount() {
const purchaseAmount = await this.Input.readLottoPurchaseAmountInput();
this.Output.printResult(purchaseAmount);
return this.setLottoPurchaseAmount(purchaseAmount);
}
// 로또 구매 금액 저장
setLottoPurchaseAmount(purchaseAmount) {
return this.CreateModel.createPurchaseModel(Number(purchaseAmount));
}
}
export default LottoGame;
전보다 코드가 깔끔해진 느낌이다! 😁
테스트 코드를 실행했을 때, 결과도 정상적으로 나온다.
✏️ 깃허브에 올리기
로또 구매 금액을 입력받고, 입력받은 금액을 출력하는 부분까지 구현하였기 때문에 깃허브에 올려준다.
📚 로또 구입 금액 유효성 검사
이제 입력받은 로또 구입 금액에 대해 유효성 검사를 실시할 것이다.
✏️ 숫자가 아닌 경우
입력받은 구입 금액은 Purchase 객체에 Number 함수를 사용해서 저장한다.
그래서 숫자가 아닌 형태는 NaN 형태가 된다.
return this.CreateModel.createPurchaseModel(Number(purchaseAmount));
이를 활용해서 먼저 숫자가 아닌 경우 유효성 검사를 한다.
#validate(amount) {
if (Number.isNaN(amount)) {
throw new Error(ERROR_MESSAGES.purchaseAmountNotNumber);
}
}
해당 에러 메시지를 출력하기 위해 함수를 호출했던 곳에서 try-catch를 사용해서 메시지를 출력한다.
그리고 이번 미션에 새로 추가된 요구사항으로 이런 내용이 있다.
사용자가 잘못된 값을 입력할 경우 throw 문을 사용해 예외를 발생시킨다.
그런 다음, "[ERROR]"로 시작하는 에러 메시지를 출력하고 해당 부분부터 입력을 다시 받는다.
그래서 로또 구매 금액을 입력받는 함수를 호출해 주었다.
// 로또 구매 금액 저장
setLottoPurchaseAmount(purchaseAmount) {
try {
return this.CreateModel.createPurchaseModel(Number(purchaseAmount));
} catch (error) {
this.Output.printResult(error.message);
this.getLottoPurchaseAmount();
}
}
(Output.printResult() 함수의 이름이 약간 모호하다.. 결과가 아니라 에러라서)
✏️ 1,000원으로 나누어 떨어지지 않는 경우
다음으로 로또 구입 금액이 1,000원으로 나누어 떨어지지 않는 경우도 역시 에러 처리를 해야 한다.
if (amount % 1000 !== 0) {
throw new Error(ERROR_MESSAGES.purchaseAmountNotDivisible);
}
그런데 테스트 실행이 안된다.. 알고 보니깐 내가 처음에 App.js에서 Purchase.js 클래스를 생성했기 때문이다.
그래서 일단 App.js에서 Purchase.js 클래스 생성하는 코드를 지우기로 했다.
지웠더니 정상적으로 실행이 된다..ㅎ
✏️ 깃허브에 올리기
예외 상황 두 가지에 대해 예외 처리를 한 것 같으니깐 깃허브에 올려준다.
📚 로또 구입 개수 구하기
다음으로는 로또 구입 개수 구하기 코드를 구현할 것이다.
이건 간단하게 Purchase.js 에서 함수를 만들면 될 것 같다.
getLottoTicketCount() {
return this.#amount / LOTTO_CONSTANT.lottoPrice;
}
그리고 출력을 하는 코드를 만들고 테스트를 실행하면 정상적으로 티켓 개수가 출력되는 것을 볼 수 있다.
this.Output.printResult(
purchase.getLottoTicketCount() + GAME_MESSAGES.lottoTicketCount,
);
✏️ 깃허브에 올리기
해당 코드로 완성됐으므로 깃허브에 올려준다.
📚 로또 발행
다음으로 구현할 것은 로또 발행이다.
✏️ MyLotto 모델 객체 생성
내가 발행한 로또들에 대한 MyLotto.js 파일을 만들었다.
class MyLotto {
#lottoList;
constructor() {
this.#lottoList = [];
}
}
export default MyLotto;
MyLotto.js 도 App.js 에서 미리 객체를 생성해 준다.
...
const myLotto = new MyLotto(output);
const lottoGame = new LottoGame(createModel, input, output, myLotto);
...
✏️ 로또 발행하기
로또 발행하는 함수를 만들어 준다.
해당 함수에서 구매한 로또 개수를 출력해 주고, MyLotto.js 에서 내가 산 로또의 번호를 발행할 것이다.
generateLottoTicket(purchase) {
const lottoTicketCount = purchase.getLottoTicketCount();
this.Output.printResult(lottoTicketCount + GAME_MESSAGES.lottoTicketCount);
this.MyLotto.buyLottoTicket(lottoTicketCount);
}
MyLotto.js 에서 먼저 발행할 로또의 개수만큼 랜덤 넘버를 생성하는 함수를 호출해 준다.
buyLottoTicket(lottoTicketCount) {
for (let cnt = 0; cnt < lottoTicketCount; cnt += 1) {
this.generateLottoTicketFromRandomNumbers();
}
}
그리고 랜덤 수는 중복되지 않은 수라서 Set을 사용하였다. 그리고 다시 배열로 만든 다음에 숫자들을 오름차순 배열을 했다.
그리고 이제 만들어진 로또 번호 배열을 lottoList 라는 배열에 넣어준다.
generateLottoTicketFromRandomNumbers() {
const lottoNumber = new Set();
while (lottoNumber.size < 6) {
lottoNumber.add(Random.pickNumberInRange(1, 45));
}
const lottoTicket = Array.from(lottoNumber).sort((a, b) => a - b);
this.setMyLottoList(lottoTicket);
}
그러면 이제 LottoGameController.js 에서 내 로또 번호 배열을 손쉽게 가져오고 활용할 수 있게 된다.
setMyLottoList(lottoTicket) {
this.Output.printResult(lottoTicket);
this.#lottoList.push(lottoTicket);
}
테스트를 실행하면 정상적으로 내 로또 번호가 출력된다.
✏️ 깃허브에 올리기
해당 코드로 완성됐으므로 깃허브에 올려준다.
📚 당첨 번호 입력
다음으로 당첨 번호 입력받기이다.
이 부분에 대해서는 기존 Lotto.js 파일을 활용하여 코드를 구현할 것이다.
✏️ 당첨 번호 입력 받기
입력 받는 부분은 위에서 했던 로또 구입 금액 입력 받기와 비슷하게 구현하였다.
InputView.js 에서 입력받는 부분을 구현하고
async readLottoWinningNumbersInput() {
Console.print(GAME_MESSAGES.WinningNumbers);
const winngNumbers = await Console.readLineAsync();
return winngNumbers;
}
테스트를 실행하면 정상적으로 당첨 번호를 입력받은 것을 볼 수 있다.
async getLottoWinningNumbers() {
const winngNumbers = await this.Input.readLottoWinningNumbersInput();
this.Output.printResult(winngNumbers);
}
✏️ 당첨 번호 객체에 저장
입력받은 당첨 번호를 이제 Lotto.js 에 저장을 할 것이다. 이것도 전에 했던 것처럼 똑같이 구현하였다.
// 당첨 번호 입력 받기
async getLottoWinningNumbers() {
const winngNumbers = await this.Input.readLottoWinningNumbersInput();
this.Output.printResult(winngNumbers);
return this.setLottoWinngNumbers(winngNumbers);
}
// 당첨 번호 저장
setLottoWinngNumbers(winngNumbers) {
try {
return this.CreateModel.createLottoModel(winngNumbers);
} catch ({ message }) {
this.Output.printResult(message);
// this.getLottoWinningNumbers();
return null;
}
}
테스트를 실행했더니 출력결과가 이렇게 나왔다..
Lotto.js 에 배열로 저장해야 되는구나..
문자열을 배열로 만드는 함수를 새로 만들어야겠다.
stringToNumberArray(string) {
return string.split(",").map(Number);
}
✏️ 깃허브에 올리기
해당 코드로 완성됐으므로 깃허브에 올려준다.
📚 당첨 번호 유효성 검사
다음은 유효성 검사이다.
내가 문서에 아래 내용으로 작성했는데, 배열로 만든 상태에서 유효성 검사라서 다시 생각해 봐야 될 것 같다.
콤마 사이에 공백인 경우
1번, 2번 예시 같은 경우는 빈 곳을 0으로 인식을 하여 6자리가 아닌 경우에 예외가 걸리고,
3번 예시 같은 경우는 Number() 를 사용해서 배열을 만들었기 때문에 공백은 무시되고 정상적으로 배열로 만들어진다.
그러면 ,2,3,4,5,6 같은 경우는 배열로 [0,2,3,4,5,6] 이 만들어져 1부터 45까지 수가 아닌 경우에서 예외가 걸린다.
그래서 콤마 사이에 공백인 경우 부분은 예외 처리하는 부분에서 빼면 될 것 같다.
✏️ 숫자가 중복된 경우
6자리가 아닌 것은 처음부터 이미 구현되어 있었기 때문에 숫자가 중복된 경우를 구현할 것이다.
이 방법은 Set 을 사용해서 길이가 6인지 판별하면 될 것 같다.
if (new Set(numbers).size !== 6) {
throw new Error("[ERROR] 로또 번호는 중복되지 않은 수여야 합니다.");
}
바로 구현하고 테스트를 실행하면 정상적으로 예외처리가 된다!
✏️ 1부터 45까지 수가 아닌 경우
다음은 1부터 45까지 수가 아닌 경우이다.
배열에서 하나라도 조건에 만족하지 못하면 false를 반환하는 some 을 사용했다.
if (numbers.some((num) => Number.isNaN(num) || num < 1 || num > 45)) {
throw new Error("[ERROR] 로또 번호는 1부터 45까지의 수여야 합니다.");
}
그런데 숫자 판별하는 부분이랑 1부터 45까지 수인지 판별하는 부분을 따로 하는 게 나을 것 같다..
if (numbers.some((num) => Number.isNaN(num))) {
throw new Error("[ERROR] 로또 번호는 숫자여야 합니다.");
}
if (numbers.some((num) => num < 1 || num > 45)) {
throw new Error("[ERROR] 로또 번호는 1부터 45까지의 수여야 합니다.");
}
테스트 코드를 실행했더니 잘 실행된다!
상수 처리
이제 문구랑 숫자들을 상수처리 해줄 것이다.
그런데..상수처리를 하다가
함수가 15줄 넘어갔다고 eslint에서 알려줬다..
prettier 파일을 보니깐 넓이가 80으로 되어 있어서 100으로 바꿨다
...
"printWidth": 100,
...
✏️ 깃허브에 올리기
에러 메시지까지 모두 상수처리를 했으므로 깃허브에 올려준다.
📚 보너스 번호 입력
다음은 보너스 번호 입력받기이다.
이것도 로또 번호 입력받기 처럼 숫자 입력 받고 배열로 클래스 객체에 저장하면 될 것 같다.
✏️ 보너스 번호 입력 받기
이 부분은 위에 로또 번호 입력받은 거랑 똑같다...
// 보너스 번호 입력 받기
async getLottoBonusNumber() {
const bonusNumber = await this.Input.readLottoBonusNumberInput();
this.Output.printResult(bonusNumber);
const bonusNumberArray = this.stringToNumberArray(bonusNumber);
return this.setLottoBonusNumber(bonusNumberArray);
}
// 보너스 번호 저장
setLottoBonusNumber(bonusNumber) {
try {
return this.CreateModel.createBonusModel(bonusNumber);
} catch ({ message }) {
this.Output.printResult(message);
// this.getLottoBonusNumber();
return null;
}
}
그런데 위랑 코드 형식이 똑같아서 나중에 이걸 더 줄여야 될 것 같다!
테스트를 실행했더니 순서대로 처리되지 않았다.
아마 비동기 처리 때문일 거 같아서 함수를 호출하기 전에 await 를 붙여 줬더니 이제 정상적으로 출력이 됐다.
✏️ 깃허브에 올리기
보너스 번호 입력받는 부분이 구현됐기 때문에 깃허브에 올려준다.
📚 보너스 번호 유효성 검사
보너스 번호 유효성 검사도 로또 번호 유효성 검사와 비슷할 거 같다.
✏️ 1자리 숫자가 아닌 경우
이 부분은 쉽게 길이가 1이 아닐 경우 예외 처리를 하였다.
#validate(number) {
if (number.length !== 1) {
throw new Error("[ERROR] 보너스 번호는 1개여야 합니다.");
}
}
만약 보너스 번호를 두 개 입력했으면 이렇게 예외가 발생한다.
✏️ 1부터 45까지 수가 아닌 경우
이 부분도 위에서 했던 거 그대로 똑같이 하면 된다.
if (number.some((num) => Number.isNaN(num))) {
throw new Error("[ERROR] 보너스 번호는 숫자여야 합니다.");
}
if (number.some((num) => num < LOTTO_CONSTANT.minNumber || num > LOTTO_CONSTANT.maxNumber)) {
throw new Error("[ERROR] 보너스 번호는 1부터 45까지의 수여야 합니다.");
}
테스트를 실행하면 정상적으로 예외가 발생하는 것을 볼 수 있다.
✏️ 당첨 번호와 중복된 경우
당첨 번호를 가져와야 한다. 어떻게 할까.. 계속 객체를 전달전달 해줘야 할까..? 일단 그렇게 하기로 했다.
계속 인자로 전달전달 해서 Bonus.js 까지 도착을 했다.
이제 로또 번호 안에 보너스 번호가 있으면 에러처리를 해주었다.
if (lottoWinngNumbers.getLotto().includes(number[0])) {
throw new Error("[ERROR] 보너스 번호가 이미 당첨 번호에 포함되어 있습니다.");
}
테스트를 실행하면 정상적으로 에러가 뜨는 것을 볼 수 있다.
그리고 에러 메시지나 숫자를 상수처리 해준다.
✏️ 깃허브에 올리기
보너스 번호 예외 처리 부분이 구현됐기 때문에 깃허브에 올려준다.
📚 당첨 내역 구하기
이제 내 로또 번호와 당첨 번호, 보너스 번호를 비교해서 당첨 내역을 구해야 한다.
✏️ Result 모델 객체 생성
당첨 내역을 저장하고 구하는 모델인 Result.js 를 만들었다.
class Result {
constructor() {
this.first = 0;
this.second = 0;
this.third = 0;
this.fourth = 0;
this.fifth = 0;
}
}
export default Result;
그리고 LottoGameController.js 에서 사용할 수 있게 App.js 에서 먼저 클래스를 생성해 준다.
const result = new Result();
const lottoGame = new LottoGame(createModel, input, output, myLotto, result);
✏️ 당첨 개수 구하기
LottoGameController.js 에서 당첨 내역을 구하기 위한 함수를 만들고
당첨 번호, 보너스 번호, 발행한 내 로또 번호를 가지고 번호가 몇 개 일치하는지 확인한도록 했다.
async lottoGamePlay() {
...
this.getLottoResult(lottoWinngNumbers, lottoBonusNumber);
}
getLottoResult(winngNumbers, bonusNumber) {
this.Result.getMatchingNumbersCount(
winngNumbers.getLotto(),
bonusNumber.getBonus(),
this.MyLotto.getMyLottoList(),
);
}
번호가 일치하는 것을 구하는 함수는 Result.js 에서 구현해 보았다.
각 내 로또들을 확인하여
getMatchingNumbersCount(winning, bonus, myLotto) {
myLotto.forEach((lotto) => {
this.checkLottoMatch(lotto, winning, bonus[0]);
});
}
자바스크립트에 내장된 filter를 사용하여 내 로또와 당첨 번호가 일치하는 것만 배열에 남겨두고,
내 로또 번호에 보너스 번호가 있는지 true, false 값을 얻어 내었다.
그래서 내 로또와 당첨 번호가 일치하는 것이 3개 이상이면 로또 등수를 확인하도록 하였다.
checkLottoMatch(myLotto, winning, bonus) {
const matchNumber = myLotto.filter((num) => winning.includes(num));
const isbonusMatch = myLotto.includes(bonus);
if (matchNumber.length >= 3) this.checkLottoRank(matchNumber, isbonusMatch);
}
함수 checkLottoRank에서는 if-else 대신 스위치를 사용하여 구현하였다
그래서 일치하는 등수에 따라 생성자의 값들을 +1 증가시켰다.
checkLottoRank(matchNumber, isbonusMatch) {
switch (matchNumber.length) {
case 6:
return this.setResult("first");
case 5:
if (isbonusMatch) return this.setResult("second");
return this.setResult("third");
case 4:
return this.setResult("fourth");
default:
return this.setResult("fifth");
}
}
setResult(rank) {
this[rank] += 1;
}
✏️ 수익률 구하기
수익률 구하는 부분도 Result.js 에서 구현했다.
상수 처리를 하여 추후에 당첨 금액이 바뀌어도 상수만 바꾸면 되어 손쉽게 수정할 수 있다.
getProfitMargin(purchase) {
const profit =
((this.fifth * LOTTO_CONSTANT.fifthReward +
this.fourth * LOTTO_CONSTANT.fourthReward +
this.third * LOTTO_CONSTANT.thirdReward +
this.second * LOTTO_CONSTANT.secondReward +
this.first * LOTTO_CONSTANT.fifthReward) /
purchase) *
100;
return profit.toFixed(1);
}
✏️ 결과 출력하기
결과는 OutPutView.js 에서 출력하도록 구현했다.
async printWinngStatistics(result, profitMargin) {
Console.print("");
Console.print("당첨 통계");
Console.print("---");
Console.print(`3개 일치 (5,000원) - ${result.fifth}개`);
Console.print(`4개 일치 (50,000원) - ${result.fourth}개`);
Console.print(`5개 일치 (1,500,000원) - ${result.third}개`);
Console.print(`5개 일치, 보너스 볼 일치 (30,000,000원) - ${result.second}개`);
Console.print(`6개 일치 (2,000,000,000원) - ${result.first}개`);
Console.print(`총 수익률은 ${profitMargin}%입니다.`);
}
☘️ 난관 시작..ㅋㅋ
여기까지 보면 코드를 잘 구현되어 가고 있는 것처럼 보이겠지만,,
갑자기 멘붕이 와서 3시간 동안 잠도 못 자고 글도 못쓰고 손에 아무것도 안 잡혔었다.
왜냐면 구현이 된 거 같은데 테스트는 처음부터 통과되지 않았다고 뜨고 감기는 걸려서 자고 싶은데 아 이렇게 제출 못하나 이런저런 생각이 들었었다 ㅋㅋㅋㅋㅋㅋㅋ쿠ㅜㅜㅜㅜㅜ
물론 잘 해결해서 무사히 제출까지 완료했다..
📚 출력 형식
우선 테스트와 출력 형식이 달랐다.
테스트 코드의 예시는 [8, 21, 23, 41, 42, 43] 이런 형식으로 출력해야 되는데
나는 [ 8, 21, 23, 41, 42, 43 ] 이렇게 출력을 하였다.
앞 뒤 공백 문제인데 새벽이라 잘 보이지 않아 이게 왜 틀린 건지 뭐가 문제인지 한참 고민했었다..
앞으로는 처음부터 테스트가 잘 통과되고 알맞게 출력되는지 확인해야겠다..
📚 예외 처리
다음은 예외 처리 부분이다.
return 하는 부분을 잘못하여 객체에 null이 반환되었고 우여곡절 끝에 문제를 해결하긴 했다..
ㅠㅠ
그래서 이날 코드 구현까지 마무리하고 새벽 4시쯤에 잠들었다
그런데 몸이 아파서 병원 갔다가 남은 테스트 코드 구현을 하고 제출한 다음에 바로 자버렸다..
☘️ 테스트 코드 구현
테스트 코드 구현은
- 로또 번호 예외 테스트
- 보너스 번호 예외 테스트
- 구매 금액 예외 테스트
- 당첨 결과 등수 테스트
이렇게 4개 구현하였다.
☘️ 후기
MVC 패턴을 구현하여 생소하였지만 전보다 코드가 깔끔해졌다고 생각이 든다.
그리고 정말 중간에 이번 3주 차 미션 통과 못 할 거 같고 여기서 끝인가..? 생각까지 들었지만 무사히 3주차 미션도 제출하고 4주 차 미션까지 공지받은 상태이다..
앞으로 후반부에 난관을 겪지 말고 초반부터 잘 확인해야겠다..
파이팅..
'💜 후기 및 활동 > 우아한 테크코스 프리코스' 카테고리의 다른 글
[우아한 테크코스/프리코스] 웹 프론트엔드 6기 4주차 회고록 (0) | 2023.11.21 |
---|---|
[우아한 테크코스/프리코스] 웹 프론트엔드 6기 2주차 회고록 (0) | 2023.11.02 |
[우아한 테크코스/프리코스] 웹 프론트엔드 6기 1주차 회고록 (0) | 2023.10.26 |
FE 개발자가 되고 싶은 짱잼이
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!