Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[로또] 김승진 미션 제출합니다. #3

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6e33a4e
docs(README): 리드미에 기능 및 클래스 목록 작성
ohksj77 Aug 6, 2023
95d2b33
feat: 난수 생성을 통한 Lotto 객체 생성
ohksj77 Aug 6, 2023
2e8060e
feat(LottoRepository): 로또 repository 저장 기능
ohksj77 Aug 6, 2023
7af6ea4
feat(InputManager): 입력 담당 클래스 및 입력 받는 함수 추가
ohksj77 Aug 6, 2023
09c870a
feat: 출력 담당 클래스 및 입력 검증 추가
ohksj77 Aug 6, 2023
94d063d
feat: 로또 발행량 계산
ohksj77 Aug 6, 2023
abbcead
feat(FrontController): 프론트 컨트롤러 추가
ohksj77 Aug 6, 2023
b7400f8
feat: 로또 티켓 발행
ohksj77 Aug 6, 2023
adb9f48
feat: 발행한 로또 티켓 출력 기능
ohksj77 Aug 6, 2023
c9ff2dc
docs(README): 열거형 및 함수 설명 추가
ohksj77 Aug 6, 2023
b0e4bb9
feat: 당첨번호 입력 기능 추가
ohksj77 Aug 6, 2023
c494bfb
feat(WinningNumber): 당첨 번호 입력 기능
ohksj77 Aug 6, 2023
80aac32
feat: 당첨 번호 입력값 검증
ohksj77 Aug 6, 2023
c685be4
docs(README): 입력값 검증 관련 리드미 추가
ohksj77 Aug 6, 2023
a725d88
test: 서비스와 입력값 검증 테스트 추가
ohksj77 Aug 6, 2023
393fc6b
refactor: 클래스 삭제 및 enum 이름 수정
ohksj77 Aug 6, 2023
344755a
feat: 결과 도출 기능 및 출력 기능
ohksj77 Aug 6, 2023
764d6a9
feat: 발행량 저장 로직 추가
ohksj77 Aug 6, 2023
3bb834e
feat: 수익률 조회 기능 추가
ohksj77 Aug 6, 2023
20d47c6
refactor: 테스트 오류 수정
ohksj77 Aug 6, 2023
b748063
refactor: 불필요 클래스 삭제
ohksj77 Aug 6, 2023
e322f89
refactor: 상수 미적용 부분 적용
ohksj77 Aug 6, 2023
ad39158
feat(OutputFormatter): 출력 문자열 변환 클래스 추가
ohksj77 Aug 6, 2023
bca2c44
docs: 완료 기능 목록 수정
ohksj77 Aug 6, 2023
dd7ecb6
feat: 에러 핸들링
ohksj77 Aug 7, 2023
9760d80
feat: 에러 핸들링
ohksj77 Aug 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# 구현할 기능 목록
[x] 랜덤 번호 생성 및 저장 기능
[x] 구입 금액 입력 기능
[x] 구입 금액 입력값 검증 기능
[x] 로또 발행 개수 계산 기능
[x] 로또 발행 기능
[x] 발행한 로또 수량 및 번호 출력 기능
[x] 당첨 번호 입력 기능
[x] 당첨 번호 입력값 검증 기능
[x] 번호 일치 여부 확인 및 당첨 여부 확인 기능
[x] 당첨 내역 출력 기능
[x] 수익률 계산 및 반올림 기능
[x] 수익률 출력 기능
[x] 예외 처리 및 에러 문구 출력 기능

# 구현할 클래스 목록
## WinningNumber - 당첨 번호
- compareWithLottoList() 당첨 번호와 로또 번호 비교

## Lotto - 로또 정보
- getNumbers() 로또 번호 조회

## FrontController - 프론트 컨트롤러
- playLotto() 로또 플레이

## LottoController - 로또 컨트롤러
- saveLotto() 로또 저장
- getPublishNum() 로또 발행량 계산
- publishLotto() 로또 티켓 발행
- getWinningNumber() 당첨 번호 및 보너스 번호 저장후 조회
- checkEarningRate() 수익률 조회

## LottoService - 로또 서비스
- saveLotto() 랜덤한 숫자 생성을 통한 Lotto 생성 및 저장
- savePublishNum() 로또 발행량 계산 및 저장
- publishLotto() 로또 티켓 발행
- saveWinningNumber() 당첨 번호 저장
- checkWinningNumber() 당점 정보 비교 및 결과 계산
- checkEarningRate() 수익률 조회

## LottoRepository - 로또 레포지토리
- saveLotto() Lotto 객체 저장
- saveWinningNumber() WinningNumber 객체 저장
- findAllLotto() 로또 전체 조회
- findWinningNumber() 당첨 번호 조회
- savePublishNumber() 발행량 저장
- findPublishNumber() 발행량 조회
- saveRewardAmount() 당첨금 저장
- findRewardAmount() 당첨금 조회

## InputManager - 입력 받기
- buyAmountInput() 구매 금액 입력
- winningNumberInput() 당첨 번호 입력
- bonusNumberInput() 보너스 번호 입력

## InputValidator - 입력 검증
- validateIsNumeric() 입력값 숫자인지 검증
- validateMultiplyOfThousand() 1000의 배수인지 검증
- validateIsListWithComma() 콤마로 구분된 숫자들의 나열인지 검증

## OutputManager - 출력하기
- printStartMessage() 로또 시작 메시지 출력
- printPublishNum() 로또 발행 개수 메시지 출력
- printLottoList() 발행한 로또 티켓 출력
- printCreateWinningNumber() 당첨 번호 입력 메시지 출력
- printCreateBonusNumber() 보너스 번호 입력 메시지 출력
- printResult() 결과 정보 출력
- printEarningRate() 수익률 출력
- printErrorMessage() 에러 메시지 출력

## ResultMap - 결과 종류 마다의 개수 저장
- getResultMap() 결과 관련 map 조회
- getRewardAmount() 최종 얻은 수익 계산

## RewardMoneyMap - 당첨금 관련 매핑 정보 저장
- getRewardMoney() 개수에 따른 RewardMoney 조회
- getMatchNum() RewardMoney에 따른 개수 조회

## OutputFormatter - 출력 String 포매팅
- formatResultString() 결과 string 포맷
- formatEarningRateString() 수익률 string 포맷
- formatPublishNum() 발행 개수 string 포맷

## ComponentFactory - 컴포넌트들의 생성

# Enum 목록
## LottoMessage - 로또 진행 메시지

## ErrorMessage - 에러 메시지

## LottoNumberRange - 로또 생성 범위

## RewardMoney - 당첨금 정보
4 changes: 3 additions & 1 deletion src/main/java/lotto/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
final ComponentFactory componentFactory = new ComponentFactory();
final FrontController frontController = componentFactory.frontController();
frontController.playLotto();
}
}
36 changes: 36 additions & 0 deletions src/main/java/lotto/ComponentFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package lotto;

public class ComponentFactory {

public FrontController frontController() {
return new FrontController(lottoController(), outputManager());
}

private LottoController lottoController() {
return new LottoController(lottoService(), outputManager(), inputManager());
}

private LottoService lottoService() {
return new LottoService(lottoRepository());
}

private LottoRepository lottoRepository() {
return new LottoRepository();
}

private OutputManager outputManager() {
return new OutputManager(outputFormatter());
}

private OutputFormatter outputFormatter() {
return new OutputFormatter();
}

private InputManager inputManager() {
return new InputManager(inputValidator());
}

private InputValidator inputValidator() {
return new InputValidator();
}
}
23 changes: 23 additions & 0 deletions src/main/java/lotto/ErrorMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package lotto;

public enum ErrorMessage {
ERROR_PREFIX("[ERROR] "),
NON_NUMERIC_ERROR("숫자값만 입력 가능합니다."),
NOT_MULTIPLY_ERROR("%d의 배수만 입력 가능합니다."),
NOT_LIST_WITH_COMMA_ERROR("콤마로 구분된 %d개의 숫자 형태로만 입력 가능합니다."),
NOT_VALID_ELEMENTS_NUM("리스트의 원소 개수는 %d개여야 합니다."),
NOT_UNIQUE_ELEMENTS("리스트에 중복 원소가 존재합니다."),
CANNOT_FIND_RESULT("결과를 찾을 수 없습니다."),
NOT_VALID_LOTTO_NUMBER_ERROR("로또 번호는 1부터 45 사이의 숫자여야 합니다.");

private final String message;

ErrorMessage(final String message) {
this.message = message;
}

@Override
public String toString() {
return ERROR_PREFIX.message + this.message;
}
}
23 changes: 23 additions & 0 deletions src/main/java/lotto/FrontController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package lotto;

public class FrontController {
private final LottoController lottoController;
private final OutputManager outputManager;

public FrontController(final LottoController lottoController, final OutputManager outputManager) {
this.lottoController = lottoController;
this.outputManager = outputManager;
}

public void playLotto() {
try {
lottoController.getPublishNum();
lottoController.publishLotto();
lottoController.getWinningNumber();
lottoController.checkWinningNumber();
lottoController.checkEarningRate();
} catch (final IllegalArgumentException e) {
outputManager.printErrorMessage(e.getMessage());
}
}
}
46 changes: 46 additions & 0 deletions src/main/java/lotto/InputManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package lotto;

import camp.nextstep.edu.missionutils.Console;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class InputManager {
private static final String COMMA_SPLITTER = ",";
private final InputValidator inputValidator;

public InputManager(final InputValidator inputValidator) {
this.inputValidator = inputValidator;
}

public Integer buyAmountInput() {
final String input = Console.readLine();
inputValidator.validateIsNumeric(input);

final Integer inputNumber = Integer.valueOf(input);
inputValidator.validateMultiplyOfThousand(inputNumber);
return inputNumber;
}

public List<Integer> winningNumberInput() {
final String input = Console.readLine();
inputValidator.validateIsListWithComma(input);
return convertToList(input);
}

private List<Integer> convertToList(final String input) {
return Arrays.stream(input.split(COMMA_SPLITTER))
.map(Integer::valueOf)
.peek(inputValidator::validateLottoNumber)
.collect(Collectors.toList());
}

public Integer bonusNumberInput() {
final String input = Console.readLine();
inputValidator.validateIsNumeric(input);
final Integer bonusNumber = Integer.valueOf(input);
inputValidator.validateLottoNumber(bonusNumber);
return bonusNumber;
}
}
34 changes: 34 additions & 0 deletions src/main/java/lotto/InputValidator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package lotto;

import java.util.regex.Pattern;

public class InputValidator {
private static final String NUMERIC_MATCHER = "-?\\d+";
private static final String LIST_WITH_COMMA_MATCHER = "\\d+,\\d+,\\d+,\\d+,\\d+,\\d+";
private static final Integer NONE = 0;
private static final Integer MONEY_UNIT = 1000;

public void validateIsNumeric(final String buyAmountInput) {
if (!buyAmountInput.matches(NUMERIC_MATCHER)) {
throw new IllegalArgumentException(ErrorMessage.NON_NUMERIC_ERROR.toString());
}
}

public void validateMultiplyOfThousand(final Integer buyAmountInput) {
if (buyAmountInput % MONEY_UNIT != NONE) {
throw new IllegalArgumentException(String.format(ErrorMessage.NOT_MULTIPLY_ERROR.toString(), MONEY_UNIT));
}
}

public void validateIsListWithComma(final String input) {
if (!Pattern.matches(LIST_WITH_COMMA_MATCHER, input)) {
throw new IllegalArgumentException(String.format(ErrorMessage.NOT_LIST_WITH_COMMA_ERROR.toString(), LottoNumberRange.NUMBER_NUM));
}
}

public void validateLottoNumber(final Integer lottoNumberInput) {
if (lottoNumberInput < LottoNumberRange.MIN_RANGE.toValue() || lottoNumberInput > LottoNumberRange.MAX_RANGE.toValue()) {
throw new IllegalArgumentException(String.format(ErrorMessage.NOT_VALID_LOTTO_NUMBER_ERROR.toString()));
}
}
}
30 changes: 25 additions & 5 deletions src/main/java/lotto/Lotto.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,40 @@
package lotto;

import java.util.HashSet;
import java.util.List;

public class Lotto {
private final List<Integer> numbers;

public Lotto(List<Integer> numbers) {
public Lotto(final List<Integer> numbers) {
validate(numbers);
this.numbers = numbers;
}

private void validate(List<Integer> numbers) {
if (numbers.size() != 6) {
throw new IllegalArgumentException();
private void validate(final List<Integer> numbers) {
validateSize(numbers);
validateUnique(numbers);
}

private void validateUnique(final List<Integer> numbers) {
if (numbers.size() != new HashSet<>(numbers).size()) {
throw new IllegalArgumentException(ErrorMessage.NOT_UNIQUE_ELEMENTS.toString());
}
}

private void validateSize(final List<Integer> numbers) {
if (numbers.size() != LottoNumberRange.NUMBER_NUM.toValue()) {
throw new IllegalArgumentException(
String.format(ErrorMessage.NOT_VALID_ELEMENTS_NUM.toString(), LottoNumberRange.NUMBER_NUM.toValue()));
}
}

// TODO: 추가 기능 구현
public List<Integer> getNumbers() {
return this.numbers;
}

@Override
public String toString() {
return this.numbers.toString();
}
}
50 changes: 50 additions & 0 deletions src/main/java/lotto/LottoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package lotto;

import java.util.List;

public class LottoController {
private final LottoService lottoService;
private final OutputManager outputManager;
private final InputManager inputManager;

public LottoController(final LottoService lottoService, final OutputManager outputManager, final InputManager inputManager) {
this.lottoService = lottoService;
this.outputManager = outputManager;
this.inputManager = inputManager;
}

public void getPublishNum() {
outputManager.printStartMessage();

final Integer buyAmount = inputManager.buyAmountInput();
final Integer publishNum = lottoService.savePublishNumber(buyAmount);

outputManager.printPublishNum(publishNum);
}

public void publishLotto() {
final List<Lotto> lottoList = lottoService.publishLotto();
outputManager.printLottoList(lottoList);
}

public void getWinningNumber() {
outputManager.printCreateWinningNumber();
final List<Integer> winningNumberInput = inputManager.winningNumberInput();

outputManager.printCreateBonusNumber();
final Integer bonusNumberInput = inputManager.bonusNumberInput();

lottoService.saveWinningNumber(winningNumberInput, bonusNumberInput);
}

public void checkWinningNumber() {
outputManager.printWinningStatistics();
final ResultMap resultMap = lottoService.checkWinningNumber();
outputManager.printResult(resultMap);
}

public void checkEarningRate() {
final Double earningRate = lottoService.checkEarningRate();
outputManager.printEarningRate(earningRate);
}
}
23 changes: 23 additions & 0 deletions src/main/java/lotto/LottoMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package lotto;

public enum LottoMessage {
BUY_TO_START("구입금액을 입력해 주세요."),
PUBLISH_NUM("%d개를 구매했습니다."),
CREATE_WINNING_NUMBER("당첨 번호를 입력해 주세요."),
CREATE_BONUS_NUMBER("보너스 번호를 입력해 주세요."),
WINNING_STATISTICS("당첨 통계\n---"),
NUM_OF_MATCH("%d개 일치 (%s원) - %d개"),
BONUS_MATCH("%d개 일치, 보너스 볼 일치 (%s원) - %d개"),
EARNING_RATE("총 수익률은 %.1f%%입니다.");

private final String message;

LottoMessage(final String message) {
this.message = message;
}

@Override
public String toString() {
return this.message;
}
}
Loading