forked from knh4437/java-lotto
-
Notifications
You must be signed in to change notification settings - Fork 0
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
[로또] 어정윤 제출합니다. #2
Open
jeongyuneo
wants to merge
51
commits into
main
Choose a base branch
from
jeongyuneo
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 25 commits
Commits
Show all changes
51 commits
Select commit
Hold shift + click to select a range
daa50f6
feat: Manager 추가
jeongyuneo b2cc359
feat: Lotto Manager 추가
jeongyuneo 693dae4
feat: PurchasingMoney 추가
jeongyuneo a06762c
feat: Input 추가
jeongyuneo c0edc86
feat: LottoGenerator 추가
jeongyuneo 3530ae6
feat: IssuedLottoGenerator 추가
jeongyuneo 5cda10e
feat: Output 추가
jeongyuneo fd8c722
feat: Lottos 추가
jeongyuneo ae8f030
refactor: Lotto 패키지 이동 및 기능 추가
jeongyuneo 594210f
feat: WinningLottoGenerator 추가
jeongyuneo 3cc0e59
feat: WinningDetail 추가
jeongyuneo bb44cf0
feat: ProfileRate 추가
jeongyuneo 9b2502c
feat: BonusNumber 추가
jeongyuneo 6927b61
feat: Convertor 추가
jeongyuneo 7720622
feat: LottoResult 추가
jeongyuneo 7f09994
feat: Input - 당첨번호 입력 기능 추가
jeongyuneo 9340475
feat: Input - 보너스번호 입력 기능 추가
jeongyuneo fc380a9
feat: Output - 당첨 결과 출력 기능 추가
jeongyuneo fbff9e1
test: LottoTest - 패키지 위치 수정
jeongyuneo 8a4a9f7
test: ApplicationTest - 예외 테스트 수정
jeongyuneo b861e93
test: BonusNumberTest 추가
jeongyuneo fd76161
test: ProfitRateTest 추가
jeongyuneo 457e2d5
test: IssuedLottoGeneratorTest 추가
jeongyuneo 2e555b5
test: WinningLottoGeneratorTest 추가
jeongyuneo 7c0c0ce
refactor: Lotto - 중복 검증 기능 추가
jeongyuneo f082361
refactor: LottoManager - 발행 로또 변수 네이밍 수정
jeongyuneo d62110d
refactor: PurchasingMoney - Convertor 의존성 제거
jeongyuneo 6dc337d
refactor: BonusNumber - Convertor 의존성 제거
jeongyuneo a64f3d1
feat: PurchasingMoney - 양수 검증 기능 추가
jeongyuneo 22abd29
refactor: IssuedLottoGenerator - 싱글톤 패턴 적용
jeongyuneo 823f4a3
refactor: BonusNumber - 미사용 임포트 정리
jeongyuneo 17a5994
refactor: Lottos - quantity 필드 삭제
jeongyuneo 8d67c30
refactor: Lotto - 숫자 범위 검증 로직 수정
jeongyuneo 82f1c0c
refactor: 로또 결과 산출 로직 수정
jeongyuneo 05b2a03
style: LottoResult - 상금 값 언더바 추가
jeongyuneo fb6ca9c
refactor: 로또 비교 로직 수정
jeongyuneo 7eca028
refactor: ProfitRate - 반올림 로직 삭제
jeongyuneo 3ce2aab
test: ProfitRateTest - 소숫점 둘째 자리 반올림 테스트 수정
jeongyuneo 4239f81
refactor: BonusNumber 검증 로직 수정
jeongyuneo 51b31fb
test: BonusNumberTest - BonusNumber 생성 수정
jeongyuneo 8e212ad
refactor: PurchasingMoney - 수량 필드 삭제
jeongyuneo 760bb1d
refactor: WinningDetail - 필드 수정
jeongyuneo 0f698e1
refactor: WinningDetail - 총 상금 계산 로직 수정
jeongyuneo 35135e5
refactor: WinningDetail - toString 로직 수정
jeongyuneo 083ef2c
refactor: LottoResult - message 필드 삭제 및 toString 추가
jeongyuneo 1a689aa
refactor: 로또 당첨 결과 로직 수정
jeongyuneo b03ea09
refactor: ProfitRate - toString 추가
jeongyuneo 7c59d24
test: ProfitRateTest - 소숫점 둘째 자리 반올림 테스트 수정
jeongyuneo d43590f
refactor: Lottos - PurchasingMoney 의존성 제거
jeongyuneo cb771f5
refactor: Lottos - 수량 계산 로직 삭제
jeongyuneo 8cca416
refactor: 구매 로또 출력 로직 수정
jeongyuneo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
package lotto; | ||
|
||
import lotto.service.LottoManager; | ||
import lotto.service.Manager; | ||
|
||
public class Application { | ||
|
||
public static void main(String[] args) { | ||
// TODO: 프로그램 구현 | ||
Manager manager = new LottoManager(); | ||
manager.run(); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package lotto.domain; | ||
|
||
import lotto.util.Convertor; | ||
|
||
public class BonusNumber { | ||
|
||
private final int number; | ||
|
||
private BonusNumber(int number) { | ||
this.number = number; | ||
} | ||
|
||
public static BonusNumber from(Lotto lotto, String input) { | ||
int number = Convertor.toInteger(input); | ||
lotto.validateRange(number); | ||
lotto.validateDuplication(number); | ||
return new BonusNumber(number); | ||
} | ||
|
||
public int getNumber() { | ||
return number; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package lotto.domain; | ||
|
||
import lotto.domain.generator.LottoGenerator; | ||
import lotto.domain.result.LottoResult; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
|
||
public class Lotto { | ||
|
||
private static final int THE_NUMBER_OF_LOTTO = 6; | ||
private static final int MIN_VALUE = 1; | ||
private static final int MAX_VALUE = 45; | ||
|
||
private final List<Integer> numbers; | ||
|
||
public Lotto(List<Integer> numbers) { | ||
validateSize(numbers); | ||
validateRange(numbers); | ||
validateDuplication(numbers); | ||
this.numbers = new ArrayList<>(numbers); | ||
} | ||
|
||
public static Lotto from(LottoGenerator lottoGenerator) { | ||
return new Lotto(lottoGenerator.issue(MIN_VALUE, MAX_VALUE, THE_NUMBER_OF_LOTTO)); | ||
} | ||
|
||
public List<LottoResult> compare(Lottos issuedLotto, BonusNumber bonusNumber) { | ||
return issuedLotto.compare(numbers, bonusNumber); | ||
} | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public void validateDuplication(int bonusNumber) { | ||
if (numbers.contains(bonusNumber)) { | ||
throw new IllegalArgumentException(String.format("[ERROR] %d는 당첨 번호와 중복됩니다.", bonusNumber)); | ||
} | ||
} | ||
|
||
public void validateRange(int number) { | ||
if (isNotInRange(number)) { | ||
throw new IllegalArgumentException(String.format("[ERROR] 로또 번호는 %d부터 %d 사이의 숫자여야 합니다.", MIN_VALUE, MAX_VALUE)); | ||
} | ||
} | ||
|
||
public LottoResult getResult(List<Integer> other, BonusNumber bonusNumber) { | ||
int matchingNumber = (int) numbers.stream() | ||
.filter(other::contains) | ||
.count(); | ||
if (matchingNumber < LottoResult.FIFTH_PRIZE.getMatchingNumber()) { | ||
return LottoResult.NO_PRIZE; | ||
} | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int matchingNumberWithBonusNumber = (int) numbers.stream() | ||
.filter(number -> number == bonusNumber.getNumber()) | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.count(); | ||
return LottoResult.find(matchingNumber, matchingNumberWithBonusNumber); | ||
} | ||
|
||
public List<Integer> getNumbers() { | ||
return numbers; | ||
} | ||
|
||
private void validateSize(List<Integer> numbers) { | ||
if (numbers.size() != THE_NUMBER_OF_LOTTO) { | ||
throw new IllegalArgumentException(String.format("[ERROR] 로또 번호의 개수가 %d개가 아닙니다.", THE_NUMBER_OF_LOTTO)); | ||
} | ||
} | ||
|
||
private void validateRange(List<Integer> numbers) { | ||
numbers.stream() | ||
.filter(this::isNotInRange) | ||
.findAny() | ||
.ifPresent(number -> { | ||
throw new IllegalArgumentException(String.format("[ERROR] 로또 번호는 %d부터 %d 사이의 숫자여야 합니다.", MIN_VALUE, MAX_VALUE)); | ||
}); | ||
} | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
private boolean isNotInRange(int number) { | ||
return number < MIN_VALUE || number > MAX_VALUE; | ||
} | ||
|
||
private void validateDuplication(List<Integer> numbers) { | ||
if (new HashSet<>(numbers).size() != THE_NUMBER_OF_LOTTO) { | ||
throw new IllegalArgumentException("중복되는 번호가 포함되어 있습니다."); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package lotto.domain; | ||
|
||
import lotto.domain.generator.LottoGenerator; | ||
import lotto.domain.result.LottoResult; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
public class Lottos { | ||
|
||
private final List<Lotto> lottos; | ||
private final int quantity; | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public Lottos(List<Lotto> lottos) { | ||
this.lottos = new ArrayList<>(lottos); | ||
this.quantity = lottos.size(); | ||
} | ||
|
||
public static Lottos from(LottoGenerator lottoGenerator, PurchasingMoney purchasingMoney) { | ||
return new Lottos(Stream.generate(() -> Lotto.from(lottoGenerator)) | ||
.limit(purchasingMoney.getQuantity()) | ||
.collect(Collectors.toList())); | ||
} | ||
|
||
public List<LottoResult> compare(List<Integer> winningLotto, BonusNumber bonusNumber) { | ||
return lottos.stream() | ||
.map(lotto -> lotto.getResult(winningLotto, bonusNumber)) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public List<Lotto> getLottos() { | ||
return lottos; | ||
} | ||
|
||
public int getQuantity() { | ||
return quantity; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package lotto.domain; | ||
|
||
import lotto.util.Convertor; | ||
|
||
public class PurchasingMoney { | ||
|
||
private static final int UNIT = 1000; | ||
|
||
private final int money; | ||
private final int quantity; | ||
|
||
private PurchasingMoney(int money) { | ||
validateUnit(money); | ||
this.money = money; | ||
this.quantity = money / UNIT; | ||
} | ||
|
||
public static PurchasingMoney from(String input) { | ||
return new PurchasingMoney(Convertor.toInteger(input)); | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
public int getMoney() { | ||
return money; | ||
} | ||
|
||
public int getQuantity() { | ||
return quantity; | ||
} | ||
|
||
private void validateUnit(int money) { | ||
if (money % UNIT != 0) { | ||
throw new IllegalArgumentException(String.format("[ERROR] 구입금액은 %d원 단위여야 합니다.", UNIT)); | ||
} | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/lotto/domain/generator/IssuedLottoGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package lotto.domain.generator; | ||
|
||
import camp.nextstep.edu.missionutils.Randoms; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class IssuedLottoGenerator implements LottoGenerator { | ||
|
||
private IssuedLottoGenerator() { | ||
} | ||
|
||
public static IssuedLottoGenerator create() { | ||
return new IssuedLottoGenerator(); | ||
} | ||
jeongyuneo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
@Override | ||
public List<Integer> issue(int minValue, int maxValue, int quantity) { | ||
return Randoms.pickUniqueNumbersInRange(minValue, maxValue, quantity) | ||
.stream() | ||
.sorted() | ||
.collect(Collectors.toList()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package lotto.domain.generator; | ||
|
||
import java.util.List; | ||
|
||
public interface LottoGenerator { | ||
|
||
List<Integer> issue(int minValue, int maxValue, int quantity); | ||
} |
63 changes: 63 additions & 0 deletions
63
src/main/java/lotto/domain/generator/WinningLottoGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package lotto.domain.generator; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class WinningLottoGenerator implements LottoGenerator { | ||
|
||
private static final String DELIMITER = ","; | ||
|
||
private final String input; | ||
|
||
private WinningLottoGenerator(String input) { | ||
this.input = input; | ||
} | ||
|
||
public static WinningLottoGenerator from(String input) { | ||
return new WinningLottoGenerator(input); | ||
} | ||
|
||
@Override | ||
public List<Integer> issue(int minValue, int maxValue, int quantity) { | ||
String[] numbers = input.split(DELIMITER); | ||
validateDelimiter(numbers, quantity); | ||
validateSize(numbers, quantity); | ||
validateDuplication(numbers, quantity); | ||
validateRange(numbers, minValue, maxValue); | ||
return Arrays.stream(numbers) | ||
.map(Integer::parseInt) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private void validateDelimiter(String[] numbers, int quantity) { | ||
if (numbers.length != quantity) { | ||
throw new IllegalArgumentException(String.format("[ERROR] %s 외 구분자가 입력되었습니다.", DELIMITER)); | ||
} | ||
} | ||
|
||
private void validateDuplication(String[] numbers, int quantity) { | ||
int numberWithoutDuplication = (int) Arrays.stream(numbers) | ||
.distinct() | ||
.count(); | ||
if (numberWithoutDuplication != quantity) { | ||
throw new IllegalArgumentException("[ERROR] 당첨 번호는 중복될 수 없습니다."); | ||
} | ||
} | ||
|
||
private void validateSize(String[] numbers, int quantity) { | ||
if (numbers.length != quantity) { | ||
throw new IllegalArgumentException(String.format("[ERROR] 당첨 번호의 개수가 %d개가 아닙니다.", quantity)); | ||
} | ||
} | ||
|
||
private void validateRange(String[] numbers, int minValue, int maxValue) { | ||
Arrays.stream(numbers) | ||
.mapToInt(Integer::parseInt) | ||
.filter(number -> number < minValue || number > maxValue) | ||
.findAny() | ||
.ifPresent(number -> { | ||
throw new IllegalArgumentException(String.format("[ERROR] 로또 번호는 %d부터 %d 사이의 숫자여야 합니다.", minValue, maxValue)); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package lotto.domain.result; | ||
|
||
import java.util.Arrays; | ||
|
||
public enum LottoResult { | ||
|
||
FIRST_PRIZE(6, 0, 2000000000, "6개 일치"), | ||
SECOND_PRIZE(5, 1, 30000000, "5개 일치, 보너스 볼 일치"), | ||
THIRD_PRIZE(5, 0, 1500000, "5개 일치"), | ||
FOURTH_PRIZE(4, 0, 50000, "4개 일치"), | ||
FIFTH_PRIZE(3, 0, 5000, "3개 일치"), | ||
NO_PRIZE(0, 0, 0, ""); | ||
|
||
private final int matchingNumber; | ||
private final int matchingNumberWithBonusNumber; | ||
private final int prize; | ||
private final String message; | ||
|
||
LottoResult(int matchingNumber, int matchingNumberWithBonusNumber, int prize, String message) { | ||
this.matchingNumber = matchingNumber; | ||
this.matchingNumberWithBonusNumber = matchingNumberWithBonusNumber; | ||
this.prize = prize; | ||
this.message = message; | ||
} | ||
|
||
public static LottoResult find(int matchingNumber, int matchingNumberWithBonusNumber) { | ||
return Arrays.stream(values()) | ||
.filter(value -> value.matchingNumber == matchingNumber && value.matchingNumberWithBonusNumber <= matchingNumberWithBonusNumber) | ||
.findAny() | ||
.orElseThrow(() -> new IllegalArgumentException("[ERROR] 해당 로또에 대한 결과가 없습니다.")); | ||
} | ||
|
||
public int getMatchingNumber() { | ||
return matchingNumber; | ||
} | ||
|
||
public int getPrize() { | ||
return prize; | ||
} | ||
|
||
public String getMessage() { | ||
return message; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package lotto.domain.result; | ||
|
||
public class ProfitRate { | ||
|
||
private static final int CIPHER = 10; | ||
|
||
private final double value; | ||
|
||
private ProfitRate(double value) { | ||
this.value = value; | ||
} | ||
|
||
public static ProfitRate from(int prize, int purchasingMoney) { | ||
return new ProfitRate(round(((double) prize / purchasingMoney) * 100)); | ||
} | ||
|
||
public double getValue() { | ||
return value; | ||
} | ||
|
||
private static double round(double profitRate) { | ||
return Math.round(profitRate * CIPHER) / (double) CIPHER; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
BonusNumber의 생성자에서 lotto를 받아오는 게 어색합니다!
만약 winningLotto 보다 보너스 번호를 먼저 입력하도록 규칙이 변경된다면, 수정할 코드가 많아질 것 같아요.
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.
오.. 거기까진 생각 못했습니다. 이런게 확장 가능한 설계인가요...!
제가 생각했을 때 보너스 번호의 의미가 당첨 번호를 다 뽑은 후 말 그대로 '보너스'로 뽑는 번호라고 생각해서, 앞서 뽑은 로또 번호들과 입력으로부터 생성되는게 어색하다고 생각하지 않았습니다.
먼저 뽑은 로또 번호가 없다면 보너스 번호도 없으니까요!
윤호님 피드백을 보고 당첨 번호와 보너스 번호를 저장하는 WinningLotto라는 클래스를 선언해보았는데, 이 방식으로 구현을 하다보니 BonusNumber는 검증로직조차 없는 오로지 값만 담고 있는 클래스가 되었습니다. 저는 BonusNumber가 의미있는 값이라고 생각해서 제가 의도한 바와 다른 것 같아 해당 부분은 수정하지 않았습니다.
혹시 또 의견주시면 즐겁게 의견에 대해 고민해보겠습니당ㅎㅎ