-
Notifications
You must be signed in to change notification settings - Fork 12
[로또 게임 1단계] 리뷰 부탁드립니다 #11
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
base: jiwoo-kimm
Are you sure you want to change the base?
Changes from 35 commits
33a7d0d
e9d2001
05fbeba
538e6b8
96e6d63
fd24a8d
862c243
27424d2
39be046
c983156
f89c53e
27e69ac
9680ee3
8bd4e7f
3ee2d11
0f0a9aa
6cb70d4
dcf4842
c512869
a6ef7de
078bf69
4a83ad0
f8da3c5
a84a57e
016863a
3b93395
ddff79a
e0d1880
f4d2c40
eaac136
674ae96
a0173ea
1bf5325
ffed907
c48c8e1
2c6da43
3e67178
8d185da
60c4c70
2119239
41d2147
36c204b
1084404
2056c66
a44450b
fb57be6
a4809aa
4357c37
d1e6740
0f0371e
42ddc76
b65a98a
0f2c076
eda9666
ca56354
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,30 @@ | ||
| # java-lotto 게임 | ||
| # java-Lotto 게임 | ||
|
|
||
| # 구현 기능 목록 | ||
|
|
||
| - [x] 구입금액 입력받기 | ||
| - [x] 1000원 미만 입력 시 처리 | ||
| - [x] 1000의 배수 아닌 값 입력 시 처리 | ||
| - [x] 숫자가 아닌 값 (문자열) | ||
| - [x] 정상값 처리 | ||
| - [x] 공백 처리 | ||
| - [x] 구매 개수 구하기 | ||
| - [x] 랜덤 로또번호 구매 개수만큼 만들기 | ||
| - [x] defaultNumberSet 1번만 생성되도록 변경 | ||
| - [x] RandomLottoTest 상수 리팩토링 | ||
| - [x] PurchaseCount의 1000 접근 | ||
| - [x] 지난 주 당첨 번호 입력받기 | ||
| - [x] WinningNumbers 멤버변수 ArrayList 클래스 확인 | ||
| - [x] 숫자 개수 6개 확인 | ||
| - [x] 숫자가 아닌 값 포함 | ||
| - [x] 범위 (1~45) 확인 | ||
| - [x] 공백 처리 | ||
| - [x] 보너스 볼 입력받기 | ||
| - [x] 당첨 통계 | ||
| - [x] 당첨 조건을 enum 처리 | ||
| - [x] 일치 개수 찾기 | ||
| - [x] 5개 일치 시 보너스 볼 일치 여부 확인 | ||
| - [x] 로또 당첨 개수 구하기 | ||
| - [x] 당첨값의 합 구하기 | ||
| - [x] 수익률 구하기 | ||
| - [x] 결과 출력 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,13 @@ repositories { | |
| dependencies { | ||
| testImplementation('org.junit.jupiter:junit-jupiter:5.6.0') | ||
| testImplementation('org.assertj:assertj-core:3.15.0') | ||
|
|
||
| compileOnly 'org.projectlombok:lombok:1.18.20' | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 롬복 플러그인을 활용하셨네요!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! |
||
| annotationProcessor 'org.projectlombok:lombok:1.18.20' | ||
|
|
||
| testCompileOnly 'org.projectlombok:lombok:1.18.20' | ||
| testAnnotationProcessor 'org.projectlombok:lombok:1.18.20' | ||
|
|
||
| } | ||
|
|
||
| test { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package lotto; | ||
|
|
||
| import lotto.controller.LottoController; | ||
| import lotto.view.ConsoleInputView; | ||
| import lotto.view.ConsoleOutputView; | ||
| import lotto.view.View; | ||
|
|
||
| public class LottoApplication { | ||
|
|
||
| public static void main(String[] args) { | ||
| View view = View.builder() | ||
| .inputView(new ConsoleInputView()) | ||
| .outputView(new ConsoleOutputView()) | ||
| .build(); | ||
| LottoController lottoController = new LottoController(view); | ||
| lottoController.start(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| package lotto.controller; | ||
|
|
||
| import lotto.domain.dto.PurchasePriceInputDTO; | ||
| import lotto.domain.dto.PurchaseResultDTO; | ||
| import lotto.domain.dto.StatisticsResultDTO; | ||
| import lotto.domain.dto.WinningLottoInputDTO; | ||
| import lotto.service.LottoService; | ||
| import lotto.view.View; | ||
|
|
||
| public class LottoController { | ||
|
|
||
| private final View view; | ||
| private final LottoService lottoService; | ||
|
|
||
| public LottoController(View view) { | ||
| this.view = view; | ||
| this.lottoService = new LottoService(); | ||
| } | ||
|
|
||
| public void start() throws IllegalArgumentException { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MVC 패턴을 이용해 문제를 풀려고 시도하셨네요!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Controller가 View를 직접 활용하는 방식이 왜 바람직하지 않은지 이해가 가지 않습니다. MVC 패턴에서 Controller는 View와 Model(Service) 사이의 연결 역할을 해주기 때문에 둘 다 참조하고 있어야 하지 않나요? 또한, |
||
| try { | ||
| PurchasePriceInputDTO purchasePriceInputDTO = view.getPurchaseCost(); | ||
| PurchaseResultDTO purchaseResultDTO = lottoService.purchase(purchasePriceInputDTO); | ||
| view.printLottoPurchaseResult(purchaseResultDTO); | ||
|
|
||
| WinningLottoInputDTO winningLottoInputDTO = view.getWinningLottoAndBonus(); | ||
| StatisticsResultDTO statisticsResultDTO = lottoService.calculateResult(purchaseResultDTO, winningLottoInputDTO); | ||
| view.printLottoStatistics(statisticsResultDTO); | ||
| } catch (IllegalArgumentException e) { | ||
| view.printException(e.getMessage()); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| package lotto.domain; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.stream.IntStream; | ||
|
|
||
| public class DefaultNumbers { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 어떤 의도로 생성되었는지는 알겠습니다만, 과한 포장은 아닐까요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! RandomLotto 클래스에서 로또 생성 할 때만 사용하기 때문에 RandomLotto 클래스의 상수로 unwrap 했습니다 |
||
|
|
||
| @Getter | ||
| private static final List<Integer> defaultNumbers = Collections.unmodifiableList(new ArrayList<Integer>() {{ | ||
| IntStream.range(LottoNumber.LOWER_BOUND, LottoNumber.UPPER_BOUND) | ||
| .forEach(this::add); | ||
| }}); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package lotto.domain; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class Lotto { | ||
|
|
||
| public static final int PRICE = 1000; | ||
| public static final int LOTTO_NUMBER_SIZE = 6; | ||
|
|
||
| @Getter | ||
| protected List<LottoNumber> lottoNumbers; | ||
|
|
||
| public Lotto(List<LottoNumber> lottoNumbers) { | ||
| this.lottoNumbers = lottoNumbers; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,56 @@ | ||||||
| package lotto.domain; | ||||||
|
|
||||||
| import lombok.Getter; | ||||||
|
|
||||||
| import java.util.Objects; | ||||||
|
|
||||||
| import static lotto.exception.ExceptionMessage.NON_INTEGER_INPUT_FOR_LOTTO_NUMBER; | ||||||
| import static lotto.exception.ExceptionMessage.OUT_OF_BOUND_INPUT_FOR_LOTTO_NUMBER; | ||||||
| import static lotto.util.NumberValidateUtils.isInteger; | ||||||
|
|
||||||
| public class LottoNumber { | ||||||
|
|
||||||
| public static final int LOWER_BOUND = 1; | ||||||
| public static final int UPPER_BOUND = 45; | ||||||
|
|
||||||
| @Getter | ||||||
| private final int lottoNumber; | ||||||
|
|
||||||
| public LottoNumber(String input) throws IllegalArgumentException { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LottoNumber를 생성할 때 String으로 생성할 필요가 있을까요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
| validate(input); | ||||||
|
|
||||||
| this.lottoNumber = Integer.parseInt(input); | ||||||
| } | ||||||
|
|
||||||
| private void validate(String input) throws IllegalArgumentException { | ||||||
| if (!isInteger(input)) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! 더 명확하게 표현하도록 수정했습니다. |
||||||
| throw new IllegalArgumentException(NON_INTEGER_INPUT_FOR_LOTTO_NUMBER.getMessage()); | ||||||
| } | ||||||
|
|
||||||
| int lottoNumber = Integer.parseInt(input); | ||||||
| if (isOutOfBound(lottoNumber)) { | ||||||
| throw new IllegalArgumentException(OUT_OF_BOUND_INPUT_FOR_LOTTO_NUMBER.getMessage()); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| private boolean isOutOfBound(int lottoNumber) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||
| return lottoNumber < LOWER_BOUND || lottoNumber > UPPER_BOUND; | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public boolean equals(Object o) { | ||||||
| if (this == o) { | ||||||
| return true; | ||||||
| } | ||||||
| if (o == null || getClass() != o.getClass()) { | ||||||
| return false; | ||||||
| } | ||||||
| LottoNumber that = (LottoNumber) o; | ||||||
| return lottoNumber == that.lottoNumber; | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public int hashCode() { | ||||||
| return Objects.hash(lottoNumber); | ||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package lotto.domain; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| import java.util.Collections; | ||
| import java.util.Set; | ||
|
|
||
| public class LottoSet { | ||
|
|
||
| @Getter | ||
| private final Set<Lotto> lottoSet; | ||
|
|
||
| public LottoSet(Set<Lotto> lottoSet) { | ||
| this.lottoSet = Collections.unmodifiableSet(lottoSet); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package lotto.domain; | ||
|
|
||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
|
|
||
| public class LottoStatistics { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 통계를 담는 객체를 만든 것 아주 좋습니다 👍 |
||
|
|
||
| @Getter | ||
| private final PrizeCount prizeCount; | ||
| private final PurchaseCount purchaseCount; | ||
|
|
||
| @Builder | ||
| public LottoStatistics(PrizeCount prizeCount, PurchaseCount purchaseCount) { | ||
| this.prizeCount = prizeCount; | ||
| this.purchaseCount = purchaseCount; | ||
| } | ||
|
|
||
| public double calculateProfitRate() { | ||
| return (double) Prize.sumOfPrizeMoney(prizeCount) | ||
| / (purchaseCount.getPurchaseCount() * Lotto.PRICE); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| package lotto.domain; | ||
|
|
||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public enum Prize { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enum 활용 👏 |
||
|
|
||
| FIRST(6, false, 2000000000), | ||
| SECOND(5, true, 30000000), | ||
| THIRD(5, false, 1500000), | ||
| FOURTH(4, false, 50000), | ||
| FIFTH(3, false, 5000), | ||
| LOSE(2, false, 0); | ||
|
|
||
| private final int matchNumbersCount; | ||
| private final boolean isBonus; | ||
| private final long prizeMoney; | ||
|
|
||
| Prize(int matchNumbersCount, boolean isBonus, long prizeMoney) { | ||
| this.matchNumbersCount = matchNumbersCount; | ||
| this.isBonus = isBonus; | ||
| this.prizeMoney = prizeMoney; | ||
| } | ||
|
|
||
| public static Prize findPrize(int matchNumbersCount, boolean isBonus) { | ||
| if (matchNumbersCount <= LOSE.matchNumbersCount) { | ||
| return LOSE; | ||
| } | ||
| if (matchNumbersCount == FIFTH.matchNumbersCount) { | ||
| return FIFTH; | ||
| } | ||
| if (matchNumbersCount == FOURTH.matchNumbersCount) { | ||
| return FOURTH; | ||
| } | ||
| if (matchNumbersCount == FIRST.matchNumbersCount) { | ||
| return FIRST; | ||
| } | ||
| return dissolveSecondOrThird(isBonus); | ||
| } | ||
|
|
||
| private static Prize dissolveSecondOrThird(boolean isBonus) { | ||
| if (isBonus) { | ||
| return Prize.SECOND; | ||
| } | ||
| return Prize.THIRD; | ||
| } | ||
|
|
||
| public static long sumOfPrizeMoney(PrizeCount prizeCount) { | ||
| return prizeCount.getCountFirst() * FIRST.prizeMoney | ||
| + prizeCount.getCountSecond() * SECOND.prizeMoney | ||
| + prizeCount.getCountThird() * THIRD.prizeMoney | ||
| + prizeCount.getCountFourth() * FOURTH.prizeMoney | ||
| + prizeCount.getCountFifth() * FIFTH.prizeMoney; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| package lotto.domain; | ||
|
|
||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| public class PrizeCount { | ||
|
|
||
| private int countFirst; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 클래스의 이름이 PrizeCount이니
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵 count를 빼고 순위만 남겨서 수정했습니다! |
||
| private int countSecond; | ||
| private int countThird; | ||
| private int countFourth; | ||
| private int countFifth; | ||
|
|
||
| @Builder | ||
| public PrizeCount(LottoSet lottoset, WinningLotto winningLotto) { | ||
| for (Lotto lotto : lottoset.getLottoSet()) { | ||
| updateCounts(winningLotto.findPrizeCondition(lotto)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LottoApplication에서 가장 핵심적인 로직이 이 클래스의 객체의 생성자에 들어있습니다.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! |
||
| } | ||
| } | ||
|
|
||
| private void updateCounts(Prize prize) { | ||
| if (prize.equals(Prize.FIRST)) { | ||
| countFirst++; | ||
| return; | ||
| } | ||
| if (prize.equals(Prize.SECOND)) { | ||
| countSecond++; | ||
| return; | ||
| } | ||
| if (prize.equals(Prize.THIRD)) { | ||
| countThird++; | ||
| return; | ||
| } | ||
| if (prize.equals(Prize.FOURTH)) { | ||
| countFourth++; | ||
| return; | ||
| } | ||
| if (prize.equals(Prize.FIFTH)) { | ||
| countFifth++; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,43 @@ | ||||||
| package lotto.domain; | ||||||
|
|
||||||
| import lombok.Builder; | ||||||
| import lombok.Getter; | ||||||
|
|
||||||
| import static lotto.exception.ExceptionMessage.NON_INTEGER_INPUT_FOR_PURCHASE_MONEY; | ||||||
| import static lotto.exception.ExceptionMessage.NON_MULTIPLE_OF_LOTTO_PRICE_INPUT_FOR_PURCHASE_MONEY; | ||||||
| import static lotto.util.NumberValidateUtils.isInteger; | ||||||
|
|
||||||
| public class PurchaseCount { | ||||||
|
|
||||||
| private static final int MINIMUM_INPUT = 1000; | ||||||
|
|
||||||
| @Getter | ||||||
| private final int purchaseCount; | ||||||
|
|
||||||
| @Builder | ||||||
| public PurchaseCount(String input) { | ||||||
| input = input.trim(); | ||||||
| validate(input); | ||||||
|
|
||||||
| this.purchaseCount = Integer.parseInt(input) / Lotto.PRICE; | ||||||
| } | ||||||
|
|
||||||
| private void validate(String input) { | ||||||
| if (!isInteger(input)) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| throw new IllegalArgumentException(NON_INTEGER_INPUT_FOR_PURCHASE_MONEY.getMessage()); | ||||||
| } | ||||||
|
|
||||||
| int purchaseCount = Integer.parseInt(input); | ||||||
| if (notMatchesCondition(purchaseCount)) { | ||||||
| throw new IllegalArgumentException(NON_MULTIPLE_OF_LOTTO_PRICE_INPUT_FOR_PURCHASE_MONEY.getMessage()); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| private boolean notMatchesCondition(int input) { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
1의 상황을 2의 부분집합으로 생각하여 구현하신 것으로 추측되는데,
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵 부분집합으로 생각했던 것인데, 분리하는 게 더 명확하네요! 두 예외 분리해서 처리하도록 수정했습니다 |
||||||
| return input < MINIMUM_INPUT || notMultipleOfLottoPrice(input); | ||||||
| } | ||||||
|
|
||||||
| private boolean notMultipleOfLottoPrice(int input) { | ||||||
| return input % Lotto.PRICE != 0; | ||||||
| } | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
구현 기능 목록 작성 👍