[우테코 8기 BE] 3주차 로또 리뷰

2025. 11. 2. 16:05·우아한테크코스 8기 백엔드

3주차 미션은 Java 로또 시뮬레이터를 구현하는 것이었다. 구입 금액을 입력받아 로또를 발급하고, 당첨 번호와 보너스 번호를 입력받아 당첨 통계를 낸 뒤, 최종 수익률을 출력하는 프로그램이다.

 

2주차 자동차 경주 미션이 객체의 분리에 집중했다면, 이번 3주차 로또 미션은 2주차보다 구현해야 할 기능의 비중이 컸다고 느꼈다. MVC 패턴을 기본으로, Enum을 활용한 상태 관리, 방어적 복사의 필요성, 그리고 테스트 코드의 중요성을 깊이 있게 배울 수 있었다.

지난 주차와 마찬가지로 README.md에 기능 목록과 체크리스트를 작성하며 시작했다.

# java-lotto-precourse

## 구현 기능 목록

### 1️⃣ 로또 구입
- [x] 입력한 금액이 1,000원 단위인지 검증한다.
- [x] 구입 금액이 숫자가 아닌 경우 예외를 발생시킨다.
- [x] 구입 금액만큼 로또를 발행한다. (로또 1장 = 1,000원)
- [x] 발행된 로또의 수량을 출력한다.
- [x] 각 로또는 **1~45 범위의 중복되지 않은 6개 숫자**를 가진다.
- [x] 발행된 로또 번호를 **오름차순으로 출력한다.**

### 2️⃣ 당첨 번호 입력
- [x] 쉼표(,)로 구분된 6개의 숫자를 입력받는다.
- [x] 입력 번호 중 **중복이 있을 경우 예외 발생.**
- [x] 번호가 1~45 범위를 벗어나면 예외 발생.
- [x] 숫자가 아닌 값 입력 시 예외 발생.
- [x] 입력 개수가 정확히 6개가 아닐 경우 예외 발생.

### 3️⃣ 보너스 번호 입력
- [x] 보너스 번호가 **당첨 번호에 포함되어 있으면 예외 발생.**
- [x] 보너스 번호가 **1~45 범위 내**인지 검증한다.

### 4️⃣ 당첨 결과 계산
- [x] 각 로또 번호를 당첨 번호와 비교하여 **일치 개수 계산.**
- [x] 5개 일치 시, **보너스 번호 일치 여부**를 별도 판별.
- [x] 일치 개수에 따라 등수를 판정한다.

| 등수 | 조건 | 상금 |
|------|------|------|
| 1등 | 6개 일치 | 2,000,000,000원 |
| 2등 | 5개 + 보너스 | 30,000,000원 |
| 3등 | 5개 | 1,500,000원 |
| 4등 | 4개 | 50,000원 |
| 5등 | 3개 | 5,000원 |

### 5️⃣ 수익률 계산
- [x] 당첨 금액의 총합을 계산한다.
- [x] 수익률을 **소수점 둘째 자리에서 반올림**한다.
- [x] 형식: `총 수익률은 XX.X%입니다.`

### 6️⃣ 출력 형식 및 예외 처리
- [x] 잘못된 입력 시 `IllegalArgumentException` 발생.
- [x] 에러 메시지는 반드시 `[ERROR]` 로 시작.
- [x] 예외 발생 시 해당 입력부터 **재입력**을 요청한다.  

---

## 단위 테스트 항목
- [x] `Lotto` 생성 시 번호 유효성 검증 (6개, 범위, 중복 확인)
- [x] 금액 입력 검증 (문자, 음수, 1000원 단위 불일치)
- [x] 당첨 번호 / 보너스 번호 예외 검증
- [x] 일치 개수 및 등수 판정 테스트
- [x] 수익률 계산 정확도 테스트
- [x] `[ERROR]` 메시지 출력 검증

 


설계 방향 및 클래스 역할

     
Model Lotto - 로또 1장을 표현하는 도메인 객체
- 생성 시 6개 번호의 유효성(범위, 중복)을 스스로 검증
  LottoGenerator - Randoms 라이브러리를 활용해 로또 번호를 생성
- 중복 없는 1~45 범위의 6개 번호 반환
  LottoType (Enum) - 1등~5등 및 꽝(MISS)의 상태를 Enum으로 관리
- 각 등수의 일치 개수, 보너스 여부, 상금, 출력 메시지 등을 캡슐화
  LottoResult - 구매한 로또 목록(List<Lotto>)과 구입 금액을 저장
- 당첨 통계 계산 및 총 수익률 계산 로직 담당
View InputView - 사용자 입력 담당
- 구입 금액, 당첨 번호, 보너스 번호 입력
- 입력값의 형식 및 유효성 검증
  OutputView - 모든 출력 담당
- 구매 내역, 당첨 통계, 수익률, 에러 메시지, 안내 문구 출력
Controller LottoController - 전체 게임 흐름 제어
(입력 → 로또 발급 → 당첨/보너스 입력 → 결과 계산 → 출력)
- Model과 View를 중개
- 입력값 검증 및 예외 발생 시 재입력 처리
Application (Entry Point) Application - main() 메서드에서 LottoController를 생성하고 run() 실행
- 프로그램의 시작점 역할

 

 


 

 

이번 주차는 생각보다 다양한 Java의 오류와 구현 방법을 배울 수 있었다. 

 

1. 정수 나눗셈 문제

첫째로 가장 오랜 시간 괴롭혔던 버그이다. 기능 구현을 마치고 테스트를 실행했는데, 수익률(Rate of Return) 테스트에서 계속 AssertionFailedError가 발생했다.

로직인 (총 당첨금 / 구매 금액) * 100 은 분명히 맞았다고 생각했는데. 하지만 원인은 정수 나눗셈 때문이었다. 실수로 double 캐스팅을 빼먹어서 결과가 정확하지 않았었는데, 이를 놓쳤었다.

Java는 C나 C++처럼 타입에 민감하기에 자료형 변환을 잘 처리해줬어야 했다.

// long winningMoney, long purchaseMoney
double rateOfReturn = (double)winningMoney / purchaseMoney * 100;
// 이전에는 아래와 같이 double 캐스팅이 없었음
// rateOfReturn = winningMoney / purchaseMoney * 100;

 

2. 얕은 복사

두 번째 버그는 NsTest의 특정 테스트 케이스에서만 발생했다. 로또를 여러 장 발급할 때, 로또의 리스트가 Null이라고 나오는 오류였다. 이 버그가 까다로웠던 이유는, 실제로 application을 실행해서 게임을 진행할 땐 문제가 없었다는 것이다.

 

문제가 발생했던 코드

Lotto 생성자에 lottoNumber 리스트의 참조를 그대로 넘겼다. Lotto 내부에서 sortingNumbers()를 호출하자, lottoNumber가 가리키는 원본 리스트 자체가 정렬되었다. 테스트 환경(NsTest)은 예측된 난수 리스트를 반환할 때 이 리스트 참조를 재활용하는 것으로 보였고, 결국 모든 Lotto 객체가 동일한 리스트 참조를 공유하게 되었다.

List<Integer> lottoNumber = lottoGenerator.generate();
Lotto lotto = new Lotto(lottoNumber); // 얕은 복사 (참조 전달)
lotto.sortingNumbers(); // <- 이 부분이 원본 리스트(lottoNumber)를 정렬시킴
lottoResult.addMyLotto(lotto);

 

해결 코드 (방어적 복사)

List<Integer> lottoNumber = lottoGenerator.generate();
// 생성자로 넘길 때 새로운 ArrayList로 감싸서 '깊은 복사' 수행
Lotto lotto = new Lotto(new ArrayList<>(lottoNumber)); 
lotto.sortingNumbers(); // 이제 내부 리스트만 정렬됨
lottoResult.addMyLotto(lotto);

 

 

3. Enum을 활용한 메서드 15줄 제한 극복

프로그램을 완성하고 검토를 하는 도중, 메서드의 길이가 15줄 이상이 넘지 않도록 구현해야하는 것과, Enum을 활용해볼 것이라는 피드백을 확인할 수 있었다. 또한 값을 하드코딩하지 않도록 구현해야 했는데 완성된 코드는 모두 위 조건들을 위배하고 있었다.

 

따라서 LottoType 이라는 Enum을 도입하여 해결하였다.

Enum을 도입하여 구현하였을때 장점은 다음과 같다.

  • 장점 1 (책임 분리): 등수별 당첨 조건(matchCount, bonus), 상금(prizeMoney), 출력 메시지를 LottoType이 스스로 관리하게 했다.
  • 장점 2 (로직 단순화): LottoResult에서는 LottoType.valueOf(일치개수, 보너스여부)를 호출하기만 하면 해당 등수를 바로 얻을 수 있었다.

 

4. TestCode 작성

이번 미션에서는 2주차보다 테스트 코드의 중요성을 훨씬 더 크게 느꼈다. 단순히 기능을 검증하는 것을 넘어, 구현하면서 놓친 치명적인 버그들을 테스트 과정에서 발견할 수 있었다.

 

제공된 단위 테스트(JUnit)와 통합 테스트(NsTest)에 새롭게 테스트 코드를 추가하여 다양한 오류를 검증할 수 있었다. 아래에 테스트에 활용했던 코드를 첨부하였다.

 

ApplicationTest.java
0.00MB
LottoResultTest.java
0.00MB
LottoTest.java
0.00MB

 

 


 

 

3주차는 2주차보다 난이도가 있었지만, 그만큼 테스트의 중요성과 객체지향 설계의 디테일(방어적 복사, Enum 활용)을 배울 수 있었다. 특히 공통 피드백에서 강조한 '메서드 15줄 제한', '값을 하드코딩하지 않기' 등을 의식적으로 지키려 노력했다.

다음주는 오픈미션인데 어떤 과제가 나올지 기대된다!

 

 

 

https://github.com/woowacourse-precourse/java-lotto-8/pull/71

 

[로또] 이동건 미션 제출합니다. by mvg01 · Pull Request #71 · woowacourse-precourse/java-lotto-8

주요 구현 기능 구입 금액 입력 및 검증 구입 금액을 입력받아 1,000원 단위인지 검증합니다. 숫자가 아니거나 1,000원 단위가 아닐 경우 IllegalArgumentException을 발생시키고, [ERROR] 메시지 출력 후 해

github.com

 

'우아한테크코스 8기 백엔드' 카테고리의 다른 글

[우테코 8기 BE] 최종시험 후기 및 회고  (0) 2026.01.24
[우테코 8기 BE] 4 & 5 주차 오픈미션  (0) 2025.11.24
[우테코 8기 BE] 2주차 자동차 경주 리뷰  (0) 2025.10.27
[우테코 8기 BE] 1주차 문자열 덧셈 계산기 리뷰  (0) 2025.10.18
'우아한테크코스 8기 백엔드' 카테고리의 다른 글
  • [우테코 8기 BE] 최종시험 후기 및 회고
  • [우테코 8기 BE] 4 & 5 주차 오픈미션
  • [우테코 8기 BE] 2주차 자동차 경주 리뷰
  • [우테코 8기 BE] 1주차 문자열 덧셈 계산기 리뷰
mvg01
mvg01
지능 낮은 컴퓨터공학부 4학년의 블로그
  • mvg01
    mvg01 님의 블로그
    mvg01
  • 전체
    오늘
    어제
    • 분류 전체보기 (87)
      • 백준 문제풀이 (29)
        • bfs (13)
        • dfs (4)
        • shortest path (1)
        • implemetation (1)
        • data structure (5)
        • dynamic programming (2)
        • greedy (1)
        • brute force (0)
        • back tracking (1)
        • string (0)
        • binary search (1)
      • 드림핵 문제풀이 (42)
        • web (17)
        • reversing (6)
        • pwnable (2)
        • misc (10)
        • forensics (7)
      • 우아한테크코스 8기 백엔드 (5)
      • 정보 보안 (0)
        • WEB (0)
        • Reversing (0)
        • 시스템 해킹 (0)
        • Forensics (0)
      • 임베디드 (4)
        • NVIDIA Jetson (4)
        • raspberry pi (0)
      • AI (6)
        • Claude (3)
        • OpenAI gpt (1)
        • n8n (2)
      • 서평 (1)
  • 인기 글

  • 최근 글

  • 링크

  • hELLO· Designed By정상우.v4.10.3
mvg01
[우테코 8기 BE] 3주차 로또 리뷰
상단으로

티스토리툴바