-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
step4 #3258
base: joooahn
Are you sure you want to change the base?
step4 #3258
Changes from all commits
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,17 +1,19 @@ | ||
package lotto.domain; | ||
|
||
import lotto.exception.TicketNumberOutOfBoundException; | ||
|
||
public class BonusBall { | ||
private final Integer bonusBall; | ||
private final LottoNo bonusBall; | ||
|
||
private BonusBall(Integer bonusBall) { | ||
private BonusBall(LottoNo bonusBall) { | ||
this.bonusBall = bonusBall; | ||
} | ||
|
||
public static BonusBall from(String bonusBall) { | ||
return new BonusBall(Integer.valueOf(bonusBall)); | ||
public static BonusBall from(String bonusBall) throws TicketNumberOutOfBoundException { | ||
return new BonusBall(LottoNo.from(Integer.valueOf(bonusBall))); | ||
} | ||
|
||
public Integer getBonusBall() { | ||
public LottoNo getBonusBall() { | ||
return bonusBall; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package lotto.domain; | ||
|
||
import lotto.exception.TicketNumberOutOfBoundException; | ||
|
||
public class LottoNo { | ||
int number; | ||
|
||
private LottoNo(int number) throws TicketNumberOutOfBoundException { | ||
if (checkValid(number)) { | ||
this.number = number; | ||
} | ||
} | ||
|
||
public static LottoNo from(int number) throws TicketNumberOutOfBoundException { | ||
return new LottoNo(number); | ||
} | ||
|
||
public static LottoNo from(String string) throws TicketNumberOutOfBoundException { | ||
return new LottoNo(Integer.parseInt(string.trim())); | ||
} | ||
|
||
private boolean checkValid(int number) throws TicketNumberOutOfBoundException { | ||
if (number < 0 || number > 45) { | ||
throw new TicketNumberOutOfBoundException("1 ~ 45 범위만 입력 가능합니다."); | ||
} | ||
return true; | ||
} | ||
|
||
public int number() { | ||
return this.number; | ||
} | ||
|
||
public boolean equals(LottoNo lottoNo) { | ||
return this.number == lottoNo.number(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,84 @@ | ||
package lotto.domain; | ||
|
||
import lotto.exception.TicketNumberOutOfBoundException; | ||
import lotto.exception.TicketPriceOutOfBoundException; | ||
|
||
import java.util.*; | ||
import java.util.stream.Collectors; | ||
|
||
import static lotto.domain.Ticket.LOTTO_PRICE; | ||
|
||
public class LottoTickets { | ||
private final List<Ticket> tickets; | ||
private final Integer numberOfManualTickets; | ||
private final Integer numberOfAutoTickets; | ||
|
||
private LottoTickets(List<Ticket> tickets) { | ||
private LottoTickets(List<Ticket> tickets, int numberOfManualTickets, int numberOfAutoTickets) { | ||
this.tickets = tickets; | ||
this.numberOfManualTickets = numberOfManualTickets; | ||
this.numberOfAutoTickets = numberOfAutoTickets; | ||
} | ||
|
||
public static LottoTickets from(List<Ticket> tickets) { | ||
return new LottoTickets(tickets); | ||
return new LottoTickets(tickets, 0, 0); | ||
} | ||
|
||
public static LottoTickets of(LottoTickets manualTickets, LottoTickets autoTickets) { | ||
return new LottoTickets(manualTickets.merge(autoTickets), manualTickets.numberOfTickets(), autoTickets.numberOfTickets()); | ||
} | ||
|
||
private List<Ticket> merge(LottoTickets tickets) { | ||
List<Ticket> mergedTickets = new ArrayList<>(); | ||
mergedTickets.addAll(this.tickets); | ||
mergedTickets.addAll(tickets.getTickets()); | ||
return mergedTickets; | ||
} | ||
|
||
public int numberOfTickets() { | ||
return tickets.size(); | ||
} | ||
|
||
public int totalPrice() { | ||
return tickets.size() * 1000; | ||
return tickets.size() * LOTTO_PRICE; | ||
} | ||
|
||
public boolean checkValidTickets() { | ||
return tickets.stream().allMatch(Ticket::checkValidTickets); | ||
public static LottoTickets buyTickets(long money, List<Ticket> manualTickets) throws TicketNumberOutOfBoundException, TicketPriceOutOfBoundException { | ||
if (money < 0) { | ||
throw new TicketPriceOutOfBoundException("가격은 음수가 불가능합니다."); | ||
} | ||
int numberOfManualTicket = manualTickets.size(); | ||
int numberOfAutoTicket = (int) (money / LOTTO_PRICE) - numberOfManualTicket; | ||
return LottoTickets.of(buyManualTickets(manualTickets), buyAutoTickets(numberOfAutoTicket)); | ||
} | ||
|
||
public static LottoTickets buyTickets(long money) { | ||
return LottoGenerator.generateTickets(money); | ||
public static LottoTickets buyManualTickets(List<Ticket> tickets) { | ||
return LottoGenerator.generateManualTickets(tickets); | ||
} | ||
|
||
public static LottoTickets buyAutoTickets(long numberOfTicket) throws TicketNumberOutOfBoundException { | ||
if (numberOfTicket < 0) { | ||
throw new TicketNumberOutOfBoundException("티켓 개수는 음수가 불가능합니다."); | ||
} | ||
return LottoGenerator.generateAutoTickets(numberOfTicket); | ||
} | ||
|
||
public List<Ticket> getTickets() { | ||
return tickets; | ||
} | ||
|
||
public WinningStatus winningStatus(WinningNumber winningNumber) { | ||
List<PrizeType> prizeTypes = listOfPrize(winningNumber); | ||
return makeWinningStatus(prizeTypes); | ||
List<Prize> prizeTypesOfTickets = listOfPrize(winningNumber); | ||
return makeWinningStatus(prizeTypesOfTickets); | ||
} | ||
|
||
public List<PrizeType> listOfPrize(WinningNumber winningNumber) { | ||
public List<Prize> listOfPrize(WinningNumber winningNumber) { | ||
return tickets.stream() | ||
.map(ticket -> ticket.checkLotteryWinningStatus(winningNumber)) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private WinningStatus makeWinningStatus(List<PrizeType> prizeTypes) { | ||
Map<PrizeType, Integer> winningStatus = new HashMap<>(); | ||
Arrays.stream(PrizeType.values()) | ||
.forEach(prizeType -> winningStatus.put(prizeType, countPrizeType(prizeTypes, prizeType))); | ||
return WinningStatus.from(winningStatus); | ||
} | ||
|
||
public int countPrizeType(List<PrizeType> prizeTypes, PrizeType prizeType) { | ||
return (int) prizeTypes.stream() | ||
.filter(t -> t == prizeType) | ||
.count(); | ||
private WinningStatus makeWinningStatus(List<Prize> prizeTypesOfTickets) { | ||
return WinningStatus.from(prizeTypesOfTickets); | ||
} | ||
|
||
public double returnRate(WinningNumber winningNumber) { | ||
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. 지금 listOfPrize를 두번 만들고 있는데요, WinningStatus 만들때 totalPrice 만 같이 넘겨주면 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. winningStatus(당첨 통계), returnRate(수익를)을 구할 땐 LottoTickets에게 WinningNumber만 주고 계산하도록 구현했어요 listOfPrice를 2번 사용한다면 listOfPrice가 수정될 경우 2군데 수정해야 한다는 단점이 있지만, 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.
아래 LottoTickets 의 returnRate 메소드는
WinningStatus 에서는 아래 로직으로 대체 할 수 있을 것 같습니다.
|
||
|
@@ -64,11 +87,17 @@ public double returnRate(WinningNumber winningNumber) { | |
} | ||
|
||
private long sumOfPrize(WinningNumber winningNumber) { | ||
long sum = 0; | ||
List<PrizeType> types = listOfPrize(winningNumber); | ||
for (PrizeType type : types) { | ||
sum += type.prize(); | ||
} | ||
return sum; | ||
List<Prize> types = listOfPrize(winningNumber); | ||
return types.stream() | ||
.mapToLong(Prize::prize) | ||
.sum(); | ||
} | ||
|
||
public int getNumberOfManualTickets() { | ||
return numberOfManualTickets; | ||
} | ||
|
||
public int getNumberOfAutoTickets() { | ||
return numberOfAutoTickets; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package lotto.domain; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
|
||
public enum Prize { | ||
FIRST_PRIZE(6, false, 2_000_000_000), | ||
|
||
SECOND_PRIZE(5, true, 300_000_000), | ||
|
||
THIRD_PRIZE(5, false, 1_500_000), | ||
|
||
FOURTH_PRIZE(4, false, 50_000), | ||
|
||
FIFTH_PRIZE(3, false, 5_000), | ||
|
||
NOT_MATCHING(0, false, 0); | ||
|
||
private final Integer numberOfMatching; | ||
private final Boolean bonusMatching; | ||
private final Long prize; | ||
|
||
Prize(int numberOfMatching, boolean bonusMatching, long prize) { | ||
this.numberOfMatching = numberOfMatching; | ||
this.bonusMatching = bonusMatching; | ||
this.prize = prize; | ||
} | ||
|
||
public int numberOfMatching() { | ||
return numberOfMatching; | ||
} | ||
|
||
public static Prize create(int numberOfMatching, boolean bonusMatching) { | ||
return Arrays.stream(Prize.values()) | ||
.filter(p -> p.numberOfMatching == numberOfMatching && p.bonusMatching == bonusMatching) | ||
.findFirst() | ||
.orElse(NOT_MATCHING); | ||
} | ||
|
||
public static Map<Prize, Long> winningStatus(List<Prize> prizeTypesOfTickets) { | ||
return prizeTypesOfTickets.stream() | ||
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); | ||
} | ||
|
||
private static int countPrizeType(List<Prize> prizeTypesOfTickets, Prize prize) { | ||
return (int) prizeTypesOfTickets.stream() | ||
.filter(t -> t == prize) | ||
.count(); | ||
} | ||
|
||
public long prize() { | ||
return prize; | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,15 @@ | ||||||||||||||||||||||||||||||||||||||
package lotto.domain; | ||||||||||||||||||||||||||||||||||||||
import java.util.function.Function; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
class ThrowableFunctionWrapper { | ||||||||||||||||||||||||||||||||||||||
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 Function wrapper(ThrowableFunctionalInterface function) { | ||||||||||||||||||||||||||||||||||||||
return t -> { | ||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||
return function.apply(t); | ||||||||||||||||||||||||||||||||||||||
} catch (Exception e) { | ||||||||||||||||||||||||||||||||||||||
throw new RuntimeException(); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+5
to
+13
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. wrapper 에서도 제네릭 타입을 표시해주어야 할 것 같아요 :)
Suggested change
|
||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package lotto.domain; | ||
|
||
@FunctionalInterface | ||
interface ThrowableFunctionalInterface<T, R, E extends Exception> { | ||
R apply(T t) throws E; | ||
} |
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.
LottoTickets
의 책임이 점점 많아지고 있어요.다른 객체로 책임을 분산 할 수 없나 고민해볼까요? 🤔