Skip to content
Closed
Show file tree
Hide file tree
Changes from 6 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
20 changes: 19 additions & 1 deletion src/main/java/lotto/LottoApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lotto.domain.*;
import lotto.view.LottoView;

import java.util.ArrayList;
import java.util.List;

public class LottoApplication {
Expand All @@ -11,7 +12,24 @@ public static void main(String[] args) {
LottoView lottoView = new LottoView();

Money money = new Money(lottoView.inputMoney());
Lottos lottos = lottoSystem.buyLottos(money);
lottoSystem.setLottoCount(money);

int numberOfManualLotto = lottoView.inputNumberOfManualLotto();
lottoSystem.validateNumberOfManualLotto(numberOfManualLotto);

List<Lotto> allLottos = new ArrayList<>();

lottoView.printManualLottosDescription();
for (int i = 0; i < numberOfManualLotto; i++) {
List<Integer> manualNumbers = lottoView.inputManualLottos();
Lotto lotto = lottoSystem.convertNumbersToLotto(manualNumbers);
allLottos.add(lotto);
Comment on lines +25 to +26

Choose a reason for hiding this comment

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

lottoSystem의 역할은 무엇인가요? 메서드들을 보니 책임이 하나인 것 같지는 않아서요.

Copy link
Author

@riroan riroan Apr 15, 2024

Choose a reason for hiding this comment

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

로또 플레이할 때 필요한 기능들을 모아둔 클래스입니다. 어떻게 쪼개야할 지 몰라서 한 클래스에 모두 들어간 느낌이네요..

}

List<Lotto> autoLottos = lottoSystem.buyAutoLotto(numberOfManualLotto);
allLottos.addAll(autoLottos);

Lottos lottos = new Lottos(allLottos);
lottoView.printLottos(lottos);

List<Integer> answerAndBonusNumber = lottoView.inputAnswer();
Expand Down
40 changes: 23 additions & 17 deletions src/main/java/lotto/LottoSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,50 @@ private long calculateLottoCount(Money money) {
return money.divide(LOTTO_PRICE);
}

public Lottos buyLottos(Money money) {
lottoCount = calculateLottoCount(money);
return generateLottos();
public List<Lotto> buyAutoLotto(int numberOfManualLotto) {
return generateAutoLottos(lottoCount - numberOfManualLotto);
}

public void validateNumberOfManualLotto(int numberOfManualLotto) {
if (numberOfManualLotto > lottoCount || numberOfManualLotto < 0) {
throw new IllegalArgumentException("유효하지 않은 수동 구매 개수입니다!");
}
}

public WinningNumber convertToAnswer(List<Integer> answerAndBonusNumber) {
List<Ball> answerBalls = answerAndBonusNumber.subList(0, 6)
.stream()
.map(Ball::new)
.collect(Collectors.toList());
Lotto lotto = convertNumbersToLotto(answerAndBonusNumber.subList(0, 6));
Ball bonusBall = new Ball(answerAndBonusNumber.get(6));

Lotto lotto = new Lotto(answerBalls);
return new WinningNumber(lotto, bonusBall);
}

private Lottos generateLottos() {
return numberGenerator.generateLottos(lottoCount);
public Lotto convertNumbersToLotto(List<Integer> numbers) {
List<Ball> balls = numbers.stream()
.map(Ball::new)
.collect(Collectors.toList());
return new Lotto(balls);
}

private List<Lotto> generateAutoLottos(long count) {
return numberGenerator.generateAutoLottos(count);
}

public void scoreLottos(Lottos lottos, WinningNumber winningNumber) {
for (int i = 0; i < lottoCount; i++) {
scoreLotto(lottos.get(i), winningNumber);
}
lottos.scoreLottos(winningNumber, result);
}

public Result getResult() {
return result;
}

public void scoreLotto(Lotto lotto, WinningNumber winningNumber) {
result.scoreLotto(lotto, winningNumber);
}

public Profit calculateProfit() {
long reward = result.calculateReward();
long seed = lottoCount * LOTTO_PRICE.getValue();

return new Profit(reward, seed);
}

public void setLottoCount(Money money) {
lottoCount = calculateLottoCount(money);
}
}
2 changes: 1 addition & 1 deletion src/main/java/lotto/domain/Lotto.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ private void validateBalls(List<Ball> balls) {

private void validateNumberOfBalls(List<Ball> balls) {
if (balls.size() != LOTTO_SIZE) {
throw new RuntimeException();
throw new IllegalStateException("로또 볼의 개수는 6개여야합니다!");
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/lotto/domain/Lottos.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,14 @@ public int getSize() {
public Lotto get(int ix) {
return values.get(ix);
}

Comment on lines 17 to +20

Choose a reason for hiding this comment

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

이 메서드는 view에서 사용하고 있는데요. 웹 환경이라면 해당 메서드는 호출 가능한가요?
getter를 사용하지 말라는 말은 도메인 모델끼리 비즈니스 요구 사항을 풀어내는 경우를 말합니다.
view에서는 getter를 사용해 데이터를 출력하는 하면 됩니다.

Copy link
Author

Choose a reason for hiding this comment

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

이 코멘트는 무슨 의미인지 이해하지 못했습니다.. 🤔
get메소드를 view에서만 사용하기 때문에 웹에서는 사용하지 않게 되어 사라질 메소드라 지양하는 의미로 받아들였는데 마지막 줄의 getter를 사용하여 데이터를 출력하라는게 무슨 의미인지 모르겠습니다.

Choose a reason for hiding this comment

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

https://edu.nextstep.camp/s/MCLQmhAp/ls/DO2AJZZW

젤 아래에 getter 메소드 없이 구현 가능한가? 를 읽어보시면 좋을 거 같아요.
출력을 위해 DTO를 만드는 경우 getter를 사용하고 혹은 view에 도메인 객체가 나간다면 getter를 통해서 데이터를 그대로 꺼내면 된다는 의미 입니다.

public void scoreLottos(WinningNumber winningNumber, Result result) {
for (Lotto lotto: values) {
scoreLotto(lotto, winningNumber, result);
}
}

private void scoreLotto(Lotto lotto, WinningNumber winningNumber, Result result) {
result.scoreLotto(lotto, winningNumber);
}
Comment on lines +21 to +27

Choose a reason for hiding this comment

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

    public Result scoreLottos(WinningNumber winningNumber) {
        return new Result(
            values.stream()
                .map(it -> winningNumber.match(it))
                .collect(Collectors.groupingBy(it -> it, Collectors.counting()))
        );
    }

이런 방법도 있을 것 같아요.

이 경우 테스트는 더 유연해 지지 않을까요? 테스트 코드는 어떻게 변경될 수 있을까요?

Choose a reason for hiding this comment

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

Result.reward는 필드에 꼭 필요할까요? 내부 Map 에서 계산할 수 있지 않을까요?

}
8 changes: 6 additions & 2 deletions src/main/java/lotto/domain/Money.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import java.util.Objects;

public class Money {
private final long value;
private long value;

public Money(long value) {
this.value = value;
Expand All @@ -13,10 +13,14 @@ public long getValue() {
return this.value;
}

public long divide (Money money) {
public long divide(Money money) {
return this.value / money.getValue();
}

public void subtract(Money money) {
this.value -= money.value;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
31 changes: 9 additions & 22 deletions src/main/java/lotto/generator/RandomLottoGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,38 @@

import lotto.domain.Ball;
import lotto.domain.Lotto;
import lotto.domain.Lottos;
import lotto.domain.WinningNumber;

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

public class RandomLottoGenerator {
private static final int MIN_NUMBER = 1;
private static final int MAX_NUMBER = 45;
private static final int LENGTH = 6;
private final List<Ball> ballPool;
private final List<Ball> ballPool = IntStream.rangeClosed(MIN_NUMBER, MAX_NUMBER)
.mapToObj(Ball::new)
.collect(Collectors.toList());

public RandomLottoGenerator() {
this.ballPool = new ArrayList<>();
IntStream.rangeClosed(MIN_NUMBER, MAX_NUMBER)
.forEach(number -> ballPool.add(new Ball(number)));
}

private List<Ball> generateNumbers(int length) {
private List<Ball> generateNumbers() {
Collections.shuffle(ballPool);
return new ArrayList<>(ballPool.subList(0, length));
return new ArrayList<>(ballPool.subList(0, RandomLottoGenerator.LENGTH));
}

public Lottos generateLottos(long lottoCount) {
public List<Lotto> generateAutoLottos(long lottoCount) {
List<Lotto> lottos = new ArrayList<>();
for (int i = 0; i < lottoCount; i++) {
Lotto lotto = generateLotto();
lottos.add(lotto);
}

return new Lottos(lottos);
return lottos;
}

public Lotto generateLotto() {
List<Ball> balls = generateNumbers(LENGTH);
List<Ball> balls = generateNumbers();
return new Lotto(balls);
}

public WinningNumber generateWinningNumber() {
List<Ball> balls = generateNumbers(LENGTH + 1);
Lotto lotto = new Lotto(balls.subList(0, LENGTH));
Ball bonusBall = balls.get(LENGTH);

return new WinningNumber(lotto, bonusBall);
}
}
29 changes: 25 additions & 4 deletions src/main/java/lotto/view/LottoView.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package lotto.view;

import lotto.domain.Lotto;
import lotto.domain.Lottos;
import lotto.domain.Profit;
import lotto.enums.Ranking;
import lotto.domain.Result;
import lotto.enums.Ranking;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
Expand All @@ -19,6 +21,12 @@ public long inputMoney() {
return Long.parseLong(money);
}

public int inputNumberOfManualLotto() {
System.out.println("수동으로 구매할 로또 수를 입력해 주세요.");
String count = scan.nextLine();
return Integer.parseInt(count);
}

public void printLottos(Lottos lottos) {
int size = lottos.getSize();
System.out.printf("%d개를 구매했습니다.\n", size);
Expand All @@ -30,12 +38,16 @@ public void printLottos(Lottos lottos) {
System.out.println();
}

private List<Integer> stringToNumbers(String numbers) {
return Arrays.stream(numbers.split(", "))
.map(Integer::parseInt)
.collect(Collectors.toList());
}

public List<Integer> inputAnswer() {
System.out.println("지난 주 당첨 번호를 입력해 주세요.");
String answerLotto = scan.nextLine();
List<Integer> answerAndBonusBall = Arrays.stream(answerLotto.split(", "))
.map(Integer::parseInt)
.collect(Collectors.toList());
List<Integer> answerAndBonusBall = stringToNumbers(answerLotto);

System.out.println("보너스 볼을 입력해 주세요.");
String bonusBallNumber = scan.nextLine();
Expand All @@ -61,6 +73,15 @@ public void printResult(Result result) {
}
}

public void printManualLottosDescription() {
System.out.println("수동으로 구매할 번호를 입력해 주세요.");
}

public List<Integer> inputManualLottos() {

String lottoNumbers = scan.nextLine();
return stringToNumbers(lottoNumbers);
}

private String getGainOrLoss(Profit profit) {
long integerPart = profit.getIntegerPart();
Expand Down
12 changes: 7 additions & 5 deletions src/test/java/lotto/LottoSystemTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ public class LottoSystemTest {
void 돈_2500원으로_로또_구매_테스트() {
LottoSystem lottoSystem = new LottoSystem();
Money money = new Money(2500);
Lottos lottos = lottoSystem.buyLottos(money);
lottoSystem.setLottoCount(money);

Lottos lottos = new Lottos(lottoSystem.buyAutoLotto(0));

assertThat(lottos.getSize()).isEqualTo(2);
}

@Test
void 수익률_계산_테스트() {
LottoSystem lottoSystem = new LottoSystem();
Money money = new Money(2000);
lottoSystem.buyLottos(money);
lottoSystem.setLottoCount(new Money(2000));

Lotto lotto1 = new Lotto(Arrays.asList(
new Ball(1),
Expand All @@ -46,6 +47,8 @@ public class LottoSystemTest {
new Ball(5),
new Ball(7)
));

Lottos lottos = new Lottos(Arrays.asList(lotto1, lotto2));
WinningNumber winningNumber = new WinningNumber(
new Lotto(Arrays.asList(
new Ball(1),
Expand All @@ -56,8 +59,7 @@ public class LottoSystemTest {
new Ball(6)
)), new Ball(7));

lottoSystem.scoreLotto(lotto1, winningNumber);
lottoSystem.scoreLotto(lotto2, winningNumber);
lottoSystem.scoreLottos(lottos, winningNumber);

Profit profit = lottoSystem.calculateProfit();

Expand Down
Loading