Skip to content

Conversation

@ghtjr410
Copy link

@ghtjr410 ghtjr410 commented Dec 3, 2025

로또(수동) 과제 제출

안녕하세요!
로또(수동) 과제 제출합니다.

미션 진행 과정

  1. 기능 추가 시 컴파일 에러 없이 점진적인 리팩터링 (자동화 스크립트)
  2. 수동 로또 생성기 구현 (ManualBasedLottoGenerator)
  3. 수동/자동 구매 개수 관리 구조 설계
  4. 사용자 입력 예외 처리 및 재입력 로직 구현
  5. 당첨 번호 + 보너스 번호 검증 흐름 개선

고민했던 지점

1. ManualLottoCount vs LottoCount 통합

  • 처음에는 ManualLottoCount(0 이상)와 LottoCount(1 이상)를 분리했습니다.
  • 하지만 이 방향으로 가면 AutoLottoCount도 생기고, 비슷한 값 객체가 계속 확산되는 문제가 있었습니다.
  • 생각해보니 "1개 이상 구매해야 한다"는 LottoCount의 책임이 아니라 LottoPurchaseAmount의 책임이었습니다.
  • 1000원 이상이면 자연스럽게 1개 이상이 보장된다고 판단했습니다.
  • 결론적으로 LottoCount를 0 이상으로 변경하고, subtract() 연산을 추가해서 총/수동/자동 개수를 하나의 타입으로 표현했습니다.

2. 재입력 범위 설계

  • 당첨 번호와 보너스 번호 입력에서, 보너스만 잘못 입력해도 전체를 다시 받을지 고민했습니다.
  • WinningLotto 생성 시점에 "보너스가 당첨번호와 중복" 검증이 일어나는데, 한 묶음으로 재시도하면 UX가 불편합니다.
  • 그래서 당첨번호 → Lotto 생성까지 먼저 완료하고, 보너스 번호는 별도로 재시도하도록 분리했습니다.
  • 이 과정에서 기존 Lotto.contains() 메서드를 활용해 중복 검증 책임을 자연스럽게 위임할 수 있었습니다.

배운 점

  • 비슷한 개념이 확산될 시 통합 가능성을 먼저 검토, 정말 다른 책임일 때만 분리
  • 범용 메서드와 도메인 맥락 메시지는 충돌할 수 있고, 검증과 연산을 분리하면 해결 가능

리뷰 잘 부탁드립니다!

README.md
- 4단계 문서 링크를 `./docs/04-lotto-manual.md`로 수정하여 잘못된 링크를 정상화

04-lotto-manual.md
- 로또 4단계(수동) 요구사항 문서 신규 추가
- 기능 요구사항, 프로그래밍 규칙, 체크리스트, 구현 기능 목록 상세 기술
ManualBasedLottoGenerator.java
- 문자열 입력을 받아 로또 번호 파싱 후 Lotto 생성하도록 수동 로또 생성기 구현
- 기본 생성자에서 LottoNumberParser 주입 방식 제공

ManualBasedLottoGeneratorTest.java
- 문자열 목록 입력 시 올바른 Lotto 리스트가 생성되는지 검증 테스트 추가
04-lotto-manual.md
- 수동 로또 생성기(ManualBasedLottoGenerator) 기능 요구사항 항목 추가
- 문자열 목록을 기반으로 로또 목록을 생성하는 기능 명시
ManualLottoCount.java
- 문자열 입력을 정수로 변환하여 수동 구매 개수 생성
- null·빈값 입력 시 예외 발생 처리

ManualLottoCountTest.java
- 정상 숫자 입력 시 생성 성공 테스트
- null·빈 문자열 입력 시 예외 발생 여부 검증
ManualLottoCount.java
- 생성자 블록에서 음수 값 검증 로직 추가
- 음수 입력 시 "수동 구매 개수는 0 이상이어야 합니다." 예외 발생

ManualLottoCountTest.java
- 음수 입력 시 예외 발생 여부 검증 테스트 추가
04-lotto-manual.md
- ManualLottoCount 요구사항 항목 추가
  - 0 이상 정수 생성 조건 명시
  - 문자열 생성 지원 명시
  - 빈 문자열 및 음수 입력 시 예외 발생 명시
LottoCount.java
- 문자열 기반 생성자 추가 및 빈 문자열 검증 로직 도입
- 최소값 기준을 1 → 0 이상으로 변경
- 음수 입력 시 예외 메시지 "구매 개수는 0이상이어야 합니다."로 통일

LottoCountTest.java
- 정상 생성 가능 범위를 0 이상으로 확장한 테스트 추가
- 문자열 입력 시 빈값 예외 발생 테스트 추가
- 음수 입력 시 예외 검증으로 테스트 수정
LottoCount.java
- subtract 메서드 추가하여 다른 LottoCount와의 차감 기능 제공

LottoCountTest.java
- subtract 호출 시 정상적으로 값이 감소하는지 검증 테스트 추가
ManualLottoCount.java
- 수동 구매 개수 도메인 클래스 삭제

ManualLottoCountTest.java
- 관련 테스트 코드 전체 삭제
Application.java
- 전체 구매 수에서 수동/자동 개수 분리 로직 추가
- 수동 번호 입력 및 로또 생성 기능 연동
- 자동/수동 로또 병합 처리 메서드 추가
- 구매 개수 출력 방식 변경(수동/자동 구분 출력)

InputView.java
- 수동 구매 개수 입력 메서드 추가
- 수동 번호 리스트 입력 메서드 추가

ResultView.java
- 구매 개수 출력 형식을 변경하여 수동/자동 개수 명시
PurchasedLottos.java
- purchaseCountForDisplay 및 size 관련 메서드 제거
  (구매 수 출력 책임을 ResultView로 완전 이관)

PurchasedLottosTest.java
- purchaseCountForDisplay 검증 테스트 삭제
LottoCount.java
- subtract 호출 시 차감 가능 여부 검증 추가
- isLessThan 기반의 validateSubtractable 메서드 도입
- 차감 불가 시 "차감할 수 없습니다." 예외 발생하도록 수정

LottoCountTest.java
- subtract 정상/동일 값 케이스에 대한 CSV 기반 테스트 추가
- subtract 시 초과 차감 예외 테스트 추가
- validateSubtractable 정상/예외 케이스 테스트 추가
Application.java
- 구매 금액 입력을 `retryUntilSuccess`로 감싸 예외 발생 시 재입력 가능하도록 개선
- 수동 구매 개수 입력 시 총 구매 수 초과 여부 검증 및 재입력 처리 추가
- 수동 로또 생성 단계에도 재시도 로직 적용
- 입력 람다 처리용 `retryUntilSuccess` 유틸 메서드 추가
- manual/auto 입력 분리 메서드(`getManualLottoCount`, `getManualLottoNumbers`) 추가
Application.java
- InputView, ResultView 메서드들을 static import로 교체하여 코드 가독성 개선
- 구매 금액/수동 개수/수동 번호/당첨 번호/보너스 번호 입력에 재시도(retry) 로직 적용
- 수동 로또 번호 입력 흐름 간소화 (`getManualLottoNumbers` 제거)
- 당첨 번호 파싱 및 보너스 번호 중복 검증 로직(`validateBonusNotDuplicated`) 분리
- WinningLotto 생성 시 LottoNumber를 직접 전달하도록 수정

WinningLotto.java
- 생성자 시그니처 변경: 보너스 번호를 String → LottoNumber로 받도록 일원화
Application.java
- WinningLotto 생성 과정 분리: `generateWinningLotto` 메서드 추가
- 당첨 번호 파싱 후 바로 Lotto 객체로 생성
- 보너스 번호 검증 시 `Lotto`의 contains 사용하도록 개선
- 기존 List 기반 검증 로직을 Lotto 기반으로 단순화
Application.java
- 입력/생성 메서드 네이밍을 create* 스타일로 통일하여 책임 명확화
- 구매 로또 생성 흐름을 createManualLottos, generateAutoLottos로 단순화
- 당첨 번호 생성 흐름을 createLottoForWinning, createBonusNumber로 개선
- 전체적으로 불필요한 임시 변수 제거 및 호출 구조 간결화
WinningLotto.java
- List<LottoNumber>를 입력받는 생성자 제거하여 Lotto 기반 생성 방식으로 일원화
- 기존 int 보너스 번호 생성자는 그대로 유지
04-lotto-manual.md
- PR 링크 추가
- LottoCount 요구사항을 0 이상 생성 및 차감 검증 중심으로 업데이트
- ManualLottoCount 제거에 따른 관련 항목 삭제
- PurchasedLottos의 구매 개수 출력 기능 제거 반영
- WinningLotto 생성 방식 변경(로또 + 보너스 번호)으로 요구사항 수정
Copy link
Contributor

@javajigi javajigi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 객체의 영향을 최소화하면서 4단계 미션 👍
특별히 피드백할 것은 없는데요.
로또 생성과 관련해 추가로 도전해 봤으면 하는 부분이 있어 피드백 남겨 봅니다.
이 피드백 반영하면서 "수강신청 - 레거시 코드 리팩터링" 미션의 1단계 병행해볼 것을 추천합니다.

import java.util.List;
import lotto.domain.Lotto;

public class ManualBasedLottoGenerator {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
단, utils 성격의 객체는 아닌 것으로 보여짐

import lotto.view.ResultView;
import lotto.utils.ManualBasedLottoGenerator;

public class Application {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Application이 담당하는 책임이 너무 많아진 느낌
Lotto를 생성을 담당하는 책임을 별도의 객체로 분리해 보면 어떨까?
분리할 때 다음 피드백 참고해본다.

3단계에서 4단계로 요구사항이 변경될 때 로또를 생성하는 부분의 요구사항만 변경됐다.
로또를 생성하는 부분을 다음과 같은 구조의 인터페이스로 분리해 보는 연습을 해보면 어떨까?
이와 같이 인터페이스로 구현했을 때의 잇점에 대해 고민해 보는 시간을 가져본다.

public interface LottosGenerator {
    Lottos generate();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants