-
Notifications
You must be signed in to change notification settings - Fork 6
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
미션 제출합니다. #1
base: songpang
Are you sure you want to change the base?
미션 제출합니다. #1
Changes from 38 commits
1f05aa0
d30dc74
fab2251
6b8c6e4
0e5b374
487ebd5
ee52f11
f54c607
6ef3d82
8bf6bbb
3410619
93200f9
a2a7041
ebd4470
05f3a93
7f1f4e1
121c3fa
69abefa
0c75edc
402125c
2fe4dd3
e4404d9
1380c2a
c2d856c
5514037
df90ac2
1773b15
9036fc9
2cb46c7
db7795d
ae631a6
8b6f339
bcf2ba5
7b6046a
ac27fbd
b395ceb
602c118
9c0f645
b230094
9fd72e8
4599417
81dabd0
c3126e9
7d3da15
2b80b87
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 |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import java.util.List; | ||
|
||
import domain.lotteryStore.Lotteries; | ||
import domain.lotteryStore.LotteryStore; | ||
import domain.lotteryStore.PurchasePrice; | ||
import domain.lotteryStore.numbers.BonusNumber; | ||
import domain.lotteryStore.numbers.ManualNumbersGenerator; | ||
import domain.winningStatistics.PrizeMoney; | ||
import domain.winningStatistics.WinningStatistics; | ||
import ui.Printer; | ||
import ui.Receiver; | ||
|
||
public class Application { | ||
private final Receiver receiver; | ||
private final Printer printer; | ||
private final LotteryStore lotteryStore; | ||
|
||
public Application() { | ||
lotteryStore = new LotteryStore(); | ||
receiver = new Receiver(); | ||
printer = new Printer(); | ||
} | ||
|
||
public static void main(String[] args) { | ||
Application application = new Application(); | ||
application.run(); | ||
} | ||
|
||
public void run() { | ||
PurchasePrice purchasePrice = new PurchasePrice(receiver.receivePurchasePrice()); | ||
int purchasedCount = purchasePrice.getPurchasedCount(); | ||
int manualCount = receiver.receiveManualCount(); | ||
List<String> manualNumbers = receiver.receiveManualNumbers(manualCount); | ||
printer.printPurchasedCount(manualCount, purchasedCount); | ||
|
||
Lotteries lotteries = lotteryStore.createLotteries(purchasedCount, manualCount, manualNumbers); | ||
printer.printPurchasedLotteries(lotteries); | ||
|
||
ManualNumbersGenerator winningNumbers = new ManualNumbersGenerator(receiver.receiveWinningNumbers()); | ||
BonusNumber bonusNumber = new BonusNumber(receiver.receiveBonusNumber(), winningNumbers); | ||
|
||
WinningStatistics winningStatistics = lotteries.compareWithWinningNumbersAndBonusNumber(winningNumbers, bonusNumber); | ||
|
||
printer.printWinningStatistics(winningStatistics); | ||
printer.printTotalEarningsRate(PrizeMoney.calculateEarningsRate(winningStatistics, purchasedCount)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package domain.lotteryStore; | ||
|
||
import java.util.List; | ||
|
||
import domain.lotteryStore.numbers.BonusNumber; | ||
import domain.lotteryStore.numbers.ManualNumbersGenerator; | ||
import domain.winningStatistics.ComparisonResult; | ||
import domain.winningStatistics.WinningStatistics; | ||
|
||
public class Lotteries { | ||
private final List<Lottery> lotteries; | ||
|
||
public Lotteries(List<Lottery> lotteries) { | ||
this.lotteries = lotteries; | ||
} | ||
|
||
public WinningStatistics compareWithWinningNumbersAndBonusNumber(ManualNumbersGenerator winningNumbers, | ||
BonusNumber bonusNumber) { | ||
WinningStatistics winningStatistics = new WinningStatistics(); | ||
for (Lottery lottery : lotteries) { | ||
ComparisonResult comparisonResult = compareOneTicketNumbers(winningNumbers, bonusNumber, lottery); | ||
comparisonResult.checkRanking(winningStatistics); | ||
} | ||
|
||
return winningStatistics; | ||
} | ||
|
||
public ComparisonResult compareOneTicketNumbers(ManualNumbersGenerator winningNumbers, BonusNumber bonusNumber, | ||
Lottery lottery) { | ||
int countOfMatchingNumbers = getCountOfMatchingWinningNumbers(lottery, winningNumbers); | ||
boolean hasBonusNumber = hasBonusNumber(lottery, bonusNumber); | ||
return new ComparisonResult(countOfMatchingNumbers, hasBonusNumber); | ||
} | ||
|
||
private int getCountOfMatchingWinningNumbers(Lottery lottery, ManualNumbersGenerator winningNumbers) { | ||
return lottery.getNumbers().countMatchingNumbers(winningNumbers); | ||
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. 디미터 법칙을 지켜볼까요? 디미터 법칙을 따르다보면 lottery가 여러 행동들을 가질수 있을 것 같아요. |
||
} | ||
|
||
private boolean hasBonusNumber(Lottery lottery, BonusNumber bonusNumber) { | ||
return lottery.getNumbers().contains(bonusNumber.getBonusNumber()); | ||
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. |
||
} | ||
|
||
public Lottery get(int index) { | ||
return lotteries.get(index); | ||
} | ||
|
||
public List<Lottery> getLotteries() { | ||
return lotteries; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package domain.lotteryStore; | ||
|
||
import domain.lotteryStore.numbers.Numbers; | ||
|
||
public class Lottery { | ||
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. Lottery는 getter만 가지고 있는 자료구조 객체로 남기에는 아쉽네요 😢 |
||
private final Numbers numbers; | ||
|
||
public Lottery(Numbers numbers) { | ||
this.numbers = numbers; | ||
} | ||
|
||
public Numbers getNumbers() { | ||
return numbers; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package domain.lotteryStore; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import domain.lotteryStore.numbers.AutoNumbersGenerator; | ||
import domain.lotteryStore.numbers.ManualNumbersGenerator; | ||
import domain.lotteryStore.numbers.Numbers; | ||
|
||
public class LotteryStore { | ||
public Lotteries createLotteries(int purchasedCount, int manualCount, List<String> manualNumbers) { | ||
List<Lottery> lotteries = new ArrayList<>(); | ||
List<Lottery> manualLotteries = makeManualLotteries(manualCount, manualNumbers); | ||
List<Lottery> autoLotteries = makeAutoLotteries(purchasedCount, manualCount); | ||
|
||
lotteries.addAll(manualLotteries); | ||
lotteries.addAll(autoLotteries); | ||
|
||
return new Lotteries(lotteries); | ||
} | ||
|
||
private List<Lottery> makeManualLotteries(int manualCount, List<String> manualNumbers) { | ||
List<Lottery> manualLotteries = new ArrayList<>(); | ||
for (int i = 0; i < manualCount; i++) { | ||
Numbers numbers = new Numbers(new ManualNumbersGenerator(manualNumbers.get(i)).getManualNumbers()); | ||
manualLotteries.add(new Lottery(numbers)); | ||
} | ||
return manualLotteries; | ||
} | ||
|
||
private List<Lottery> makeAutoLotteries(int purchasedCount, int manualCount) { | ||
AutoNumbersGenerator autoNumbersGenerator = new AutoNumbersGenerator(); | ||
List<Lottery> autoLotteries = new ArrayList<>(); | ||
int autoCount = purchasedCount - manualCount; | ||
while (autoCount-- > 0) { | ||
autoLotteries.add(makeAutoLottery(autoNumbersGenerator)); | ||
} | ||
return autoLotteries; | ||
} | ||
|
||
private Lottery makeAutoLottery(AutoNumbersGenerator autoNumbersGenerator) { | ||
autoNumbersGenerator.shuffle(); | ||
Numbers numbers = new Numbers(autoNumbersGenerator.getSixNumbersFromTheFront()); | ||
return new Lottery(numbers); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package domain.lotteryStore; | ||
|
||
import ui.message.ExceptionMessage; | ||
|
||
public class PurchasePrice { | ||
private static final int PRICE_OF_ONE_LOTTERY_TICKET = 1000; | ||
|
||
private final int purchasePrice; | ||
|
||
public PurchasePrice(int purchasePrice) { | ||
validateSmallerThanPurchasePrice(purchasePrice); | ||
this.purchasePrice = purchasePrice; | ||
} | ||
|
||
private void validateSmallerThanPurchasePrice(int purchasePrice) { | ||
if (purchasePrice < PRICE_OF_ONE_LOTTERY_TICKET) { | ||
throw new IllegalArgumentException(ExceptionMessage.MUST_BUY_MORE_THAN_ONE_TICKET.getMessage()); | ||
} | ||
} | ||
|
||
public int getPurchasedCount() { | ||
return purchasePrice / PRICE_OF_ONE_LOTTERY_TICKET; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package domain.lotteryStore.numbers; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class AutoNumbersGenerator { | ||
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. ManualNumbersGenerator와 AutoNumbersGenerator를 따로 정의한 이유는 무엇인가요? 제 개인적인 의견으로는 자동이든 수동이든
이와 관련한 속성을 한 객체에서 관리하되 생성하는 로직을 외부에서 변경할 수 있도록 제공하는 편이 낫다고 생각합니다. 다른 의견 있으시다면 남겨주세요! 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 final List<Integer> autoNumbers = new ArrayList<>(); | ||
|
||
public AutoNumbersGenerator() { | ||
initiateNumbers(); | ||
} | ||
|
||
private void initiateNumbers() { | ||
for (int i = LotteryNumberRange.MINIMUM_LOTTERY_NUMBER; i <= LotteryNumberRange.MAXIMUM_LOTTERY_NUMBER; i++) { | ||
autoNumbers.add(i); | ||
} | ||
} | ||
|
||
public void shuffle() { | ||
Collections.shuffle(autoNumbers); | ||
} | ||
|
||
public List<Integer> getSixNumbersFromTheFront() { | ||
return autoNumbers.stream() | ||
.limit(6) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package domain.lotteryStore.numbers; | ||
|
||
import ui.message.ExceptionMessage; | ||
|
||
public class BonusNumber extends LotteryNumberRange { | ||
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. BonusNumber가 LotteryNumberRange를 상속한 이유는 무엇인가요?? 로또 번호와 관련한 도메인을 따로 패키지를 만들만큼 많은 클래스가 나왔는데 하나의 객체에서 관리할 수 있지 않을까요? 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. LotteryNumberRange에 제약사항들을 넣어서 관련한 클래스들에 영향을 주기 위해서 였어요. 좋지않은 방법일까요? 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. 생각해보니까 LSP를 위반하는 설계였네요,,, 수정해보겠슴니당 ㅠㅠ 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.
LSP를 위반하고 있는건 아닐까요? 🤔 |
||
private final int bonusNumber; | ||
|
||
public BonusNumber(int bonusNumber, ManualNumbersGenerator winningNumbers) { | ||
validateRange(bonusNumber); | ||
validateDuplicate(bonusNumber, winningNumbers); | ||
this.bonusNumber = bonusNumber; | ||
} | ||
|
||
public void validateDuplicate(int bonusNumber, ManualNumbersGenerator winningNumbers) { | ||
if (winningNumbers.contains(bonusNumber)) { | ||
throw new IllegalArgumentException( | ||
ExceptionMessage.BONUS_NUMBER_CANNOT_EQUAL_WINNING_NUMBERS.getMessage()); | ||
} | ||
} | ||
|
||
public int getBonusNumber() { | ||
return bonusNumber; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package domain.lotteryStore.numbers; | ||
|
||
import ui.message.ExceptionMessage; | ||
|
||
public class LotteryNumberRange { | ||
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. public static 상수를 제공함과 동시에 검증하는 비즈니스 로직을 담고 있습니다. 한 객체 내에서 상수를 private화하고 로또 번호 검증과 생성을 동시에 할 수 있지 않을까요? |
||
public static final int MINIMUM_LOTTERY_NUMBER = 1; | ||
public static final int MAXIMUM_LOTTERY_NUMBER = 45; | ||
|
||
public void validateRange(int number) { | ||
if (!isInValidRange(number)) { | ||
throw new IllegalArgumentException(ExceptionMessage.MUST_INPUT_NUMBERS_IN_VALID_RANGE.getMessage()); | ||
} | ||
} | ||
|
||
private boolean isInValidRange(Integer number) { | ||
return number >= MINIMUM_LOTTERY_NUMBER && number <= MAXIMUM_LOTTERY_NUMBER; | ||
} | ||
} |
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.
ManualNumberGenerator는 이름만 봐서 로또 번호를 생성하여 반환하는 기능을 담당하는 것으로 보여지는데, 이 메서드에서 쓰이기에는 일급 컬렉션으로도 쓰이고 있는 것 같네요.
저는 로또 번호 6개를 포장하는 다른 도메인을 생각해보는게 좋다고 생각합니다.
❓ 어떻게 생각하시나요?