Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 33 additions & 0 deletions src/main/java/com/javabom/lotto/LottoApplication.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,40 @@
package com.javabom.lotto;

import com.javabom.lotto.domain.LottoTickets;
import com.javabom.lotto.domain.LottoMachine;
import com.javabom.lotto.domain.LottoResult;
import com.javabom.lotto.domain.dto.ManualNumbersDto;
import com.javabom.lotto.domain.ticket.LottoWinningTicket;
import com.javabom.lotto.domain.vo.LottoMoney;
import com.javabom.lotto.view.InputView;
import com.javabom.lotto.view.OutputView;

import java.util.List;

public class LottoApplication {
public static void main(String[] args) {
int purchaseAmount = InputView.inputPurchaseAmount();

int numberOfManualTicket = InputView.inputNumberOfManualTicket();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InputView에서 LottoMoney객체를 한번에 받아 가져오는게 좋을듯, 기본 타입을 굳이 다 노출시킬필요도 없고 도메인 객체를 input에서 받아도 상관없어보여

LottoMoney lottoMoney=InputView.inputLottoInfo();


LottoMoney lottoMoney = new LottoMoney(purchaseAmount, numberOfManualTicket);

List<ManualNumbersDto> manualNumbersDtos = InputView.inputManualNumber(lottoMoney.getNumberOfManualTicket());

LottoTickets lottoTickets = LottoMachine.purchaseLottoTicket(manualNumbersDtos, lottoMoney.getNumberOfAutoTicket());

OutputView.printNumberOfTicket(lottoMoney);

OutputView.printLottoTickets(lottoTickets.getAllTickets());

List<Integer> winningNumbers = InputView.inputLastWinningNumbers();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WinningNumbers는 일급컬렉션으로 묶는게 좋아보여
그럼 LottoNumberGenerator에 있는 public static LottoNumber findByNumber(int number) 메소드가 없어도 될거같아.


int bonusNumber = InputView.inputBonusNumber();

LottoWinningTicket lottoWinningTicket = new LottoWinningTicket(winningNumbers, bonusNumber);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 위와 마찬가지로 View에서 바로 받아와도 문제없어


LottoResult lottoResult = lottoTickets.matchAllLotto(lottoWinningTicket);

OutputView.printWinningStatistics(lottoResult, lottoMoney);
}
}
25 changes: 25 additions & 0 deletions src/main/java/com/javabom/lotto/domain/LottoMachine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.javabom.lotto.domain;

import com.javabom.lotto.domain.dto.ManualNumbersDto;
import com.javabom.lotto.domain.number.ShuffledNumberGenerator;
import com.javabom.lotto.domain.ticket.LottoTicket;

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

public class LottoMachine {
private LottoMachine() {
}

public static LottoTickets purchaseLottoTicket(List<ManualNumbersDto> manualNumbersDtos, int numberOfAutoTicket) {
List<LottoTicket> lottoTickets = manualNumbersDtos.stream()
.map(manualNumbersDto -> LottoTicket.ofFixed(manualNumbersDto.getManualNumbers()))
.collect(Collectors.toList());

for (int i = 0; i < numberOfAutoTicket; i++) {
lottoTickets.add(LottoTicket.ofAuto(new ShuffledNumberGenerator()));
}

return new LottoTickets(lottoTickets);
}
}
36 changes: 36 additions & 0 deletions src/main/java/com/javabom/lotto/domain/LottoResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.javabom.lotto.domain;

import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

public class LottoResult {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 객체에서 객체간의 의존성을 더 잘게 쪼개고 책임을 분리해보는게 좋을것 같아

private final Map<WinningSheet, Integer> winningStatistics;

public LottoResult(List<WinningSheet> winningSheets) {
this.winningStatistics = makeStatistics(winningSheets);
}

private Map<WinningSheet, Integer> makeStatistics(List<WinningSheet> winningSheets) {
Map<WinningSheet, Integer> statistics = new EnumMap<>(WinningSheet.class);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collect의 groupingBy를 쓰는게 더 깔끔할거같아


for (WinningSheet winningSheet : WinningSheet.values()) {
statistics.put(winningSheet, winningSheet.countInList(winningSheets));
}

statistics.remove(WinningSheet.FAIL);

return Collections.unmodifiableMap(statistics);
}

public Map<WinningSheet, Integer> getWinningStatistics() {
return winningStatistics;
}

public int sumAllPrize() {
return winningStatistics.entrySet().stream()
.mapToInt(statistic -> statistic.getKey().getPrize() * statistic.getValue())
.sum();
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/javabom/lotto/domain/LottoTickets.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.javabom.lotto.domain;

import com.javabom.lotto.domain.ticket.LottoTicket;
import com.javabom.lotto.domain.ticket.LottoWinningTicket;

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

public class LottoTickets {
private final List<LottoTicket> lottoTickets;

public LottoTickets(List<LottoTicket> lottoTickets) {
this.lottoTickets = lottoTickets;
}

public LottoResult matchAllLotto(LottoWinningTicket lottoWinningTicket) {
return lottoTickets.stream()
.map(lottoWinningTicket::findMatchingSheet)
.collect(Collectors.collectingAndThen(Collectors.toList(), LottoResult::new));
}

public List<LottoTicket> getAllTickets() {
return Collections.unmodifiableList(lottoTickets);
}
}
56 changes: 56 additions & 0 deletions src/main/java/com/javabom/lotto/domain/WinningSheet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.javabom.lotto.domain;

import java.util.Arrays;
import java.util.List;

public enum WinningSheet {
FAIL(0, 0),
FIFTH(3, 5_000),
FOURTH(4, 50_000),
THIRD(5, 1_500_000),
SECOND(5, 30_000_000),
FIRST(6, 2_000_000_000);

private final int matchCount;
private final int prize;

WinningSheet(int matchCount, int prize) {
this.matchCount = matchCount;
this.prize = prize;
}

public static WinningSheet findByMatchCount(int matchCount, boolean matchBonus) {
WinningSheet findSheet = Arrays.stream(values())
.filter(winningSheet -> winningSheet.isSameMatchCount(matchCount))
.findFirst()
.orElse(WinningSheet.FAIL);

if (isThirdAndMatchBonus(findSheet, matchBonus)) {
return SECOND;
}
Comment on lines +28 to +30
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (isThirdAndMatchBonus(findSheet, matchBonus)) {
return SECOND;
}
if (findSheet.isSecond(matchBonus)) {
return SECOND;
}

이건 어때?


return findSheet;
}

private static boolean isThirdAndMatchBonus(WinningSheet winningSheet, boolean matchBonus) {
return (winningSheet.equals(THIRD) && matchBonus);
}

public int getMatchCount() {
return matchCount;
}

public int getPrize() {
return prize;
}

public int countInList(List<WinningSheet> winningSheets) {
return (int) winningSheets.stream()
.filter(this::equals)
.count();
}

private boolean isSameMatchCount(int matchCount) {
return this.matchCount == matchCount;
}
}
25 changes: 25 additions & 0 deletions src/main/java/com/javabom/lotto/domain/dto/ManualNumbersDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.javabom.lotto.domain.dto;

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

public class ManualNumbersDto {
private final List<Integer> manualNumbers;

public ManualNumbersDto(String[] manualNumbers) {
try {
this.manualNumbers = Stream.of(manualNumbers)
.map(String::trim)
.map(Integer::parseInt)
.collect(Collectors.toList());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("숫자를 입력해 주세요. - " + Arrays.toString(manualNumbers));
}
}

public List<Integer> getManualNumbers() {
return manualNumbers;
}
}
69 changes: 69 additions & 0 deletions src/main/java/com/javabom/lotto/domain/number/LottoNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.javabom.lotto.domain.number;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class LottoNumber implements Comparable<LottoNumber> {
public static final int LOTTO_NUMBER_UNDER_BOUND = 1;
public static final int LOTTO_NUMBER_UPPER_BOUND = 45;
private final int number;

private LottoNumber(int number) {
this.number = number;
}

public static LottoNumber valueOf(int number) {
validateNumber(number);
return LottoNumberCache.getLottoNumber(number);
}

public int getNumber() {
return number;
}

private static void validateNumber(int number) {
if (number < LOTTO_NUMBER_UNDER_BOUND || number > LOTTO_NUMBER_UPPER_BOUND) {
throw new IllegalArgumentException("로또 번호는 1 ~ 45 사이의 값이어야 합니다. - " + number);
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof LottoNumber)) return false;
LottoNumber that = (LottoNumber) o;
return this.number == that.number;
}

@Override
public int hashCode() {
return Objects.hash(this.number);
}

@Override
public int compareTo(LottoNumber o) {
return Integer.compare(this.number, o.number);
}

@Override
public String toString() {
return String.valueOf(number);
}

private static class LottoNumberCache {
private static final Map<Integer, LottoNumber> cache;

static {
cache = new HashMap<>();

for (int number = LOTTO_NUMBER_UNDER_BOUND; number <= LOTTO_NUMBER_UPPER_BOUND; number++) {
cache.put(number, new LottoNumber(number));
}
}

private static LottoNumber getLottoNumber(int number) {
return cache.get(number);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.javabom.lotto.domain.number;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.javabom.lotto.domain.number.LottoNumber.LOTTO_NUMBER_UNDER_BOUND;
import static com.javabom.lotto.domain.number.LottoNumber.LOTTO_NUMBER_UPPER_BOUND;

public class LottoNumberGenerator {
private static final int FIRST_ELEMENT = 0;

public static List<LottoNumber> generateRandomNumber(int size, NumberGenerator numberGenerator) {
List<Integer> numbers = numberGenerator.generate(LOTTO_NUMBER_UNDER_BOUND, LOTTO_NUMBER_UPPER_BOUND);

return convertIntegerToLottoNumber(numbers.subList(FIRST_ELEMENT, size));
}

public static List<LottoNumber> generateFixedNumber(List<Integer> numbers) {
return convertIntegerToLottoNumber(numbers);
}

private static List<LottoNumber> convertIntegerToLottoNumber(List<Integer> numbers) {
return numbers.stream()
.map(LottoNumber::valueOf)
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.javabom.lotto.domain.number;

import java.util.List;

public interface NumberGenerator {
List<Integer> generate(int min, int max);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음 나라면

Suggested change
List<Integer> generate(int min, int max);
List<Integer> generateRangeOf(int min, int max);

라고 했을거같아

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.javabom.lotto.domain.number;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class ShuffledNumberGenerator implements NumberGenerator {
@Override
public List<Integer> generate(int min, int max) {
List<Integer> numbers = IntStream.rangeClosed(min, max)
.boxed()
.collect(Collectors.toList());

Collections.shuffle(numbers);

return numbers;
}
}
Loading