Skip to content
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 #3768

Open
wants to merge 20 commits into
base: boy0516
Choose a base branch
from
Open

Step4 #3768

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
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
- [x] 로또 래퍼 클래스 구현
Copy link

Choose a reason for hiding this comment

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

스크린샷 2024-04-06 오후 11 41 00

결제 금액보다 많이 살수 없지 않을까요~?

- [x] 로또 생성자 빈값 입력 예외 처리 검증
- [x] 구입금액 입력 기능
- [ ] 구입금액 최소 단위 제한(백원 이하 오류 처리)
- [X] 구입금액 최소 단위 제한(백원 이하 오류 처리)
- [X] 랜덤 로또 번호 발급 기능
- [x] 로또 래퍼 클래스 반환
- [x] 로또 번호 6자리 생성
Expand All @@ -28,3 +28,5 @@
- [x] 수익률 산출 기능
- [X] 보너스 번호 입력 기능
- [X] 2등 상금 추가
- [X] 수동 발급 추가
- [x] 예산 지불 추가
35 changes: 28 additions & 7 deletions src/main/java/lotto/controller/LottoController.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,43 @@ public void simulateLotto() {
}

private Statistics getStatistics() {
return getLottos().computeStatistic(getWinLotto());
return getLottos(getBudget()).computeStatistic(getWinLotto());
}

private WinLotto getWinLotto() {
return InputView.inputLastWinLotto();
return InputView.retryableInputLastWinLotto();
}

private Lottos getLottos() {
Lottos lottos = new Lottos(getBudget());
ResultView.showGeneratedLottos(lottos);
private Lottos getLottos(Budget budget) {
Count manualIssueCount = getManualIssueCount(budget);

budget = budget.spend(Price.LOTTO, manualIssueCount);

Lottos manualLottos = getManualIssuedLottos(manualIssueCount);
Lottos autoLottos = getAutoIssuedLottos(budget);
Comment on lines +26 to +27
Copy link

Choose a reason for hiding this comment

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

Suggested change
Lottos manualLottos = getManualIssuedLottos(manualIssueCount);
Lottos autoLottos = getAutoIssuedLottos(budget);
Lottos manualLottos = InputView.inputSelfIssueLottos(manualIssueCount);
Lottos autoLottos = new Lottos(budget);

표현하는게 한줄인데
한번 더 메소드로 감싼 이유가 궁금해요 🤔
이것때문에 복잡해진다고 느껴져서요 🤔

Copy link

Choose a reason for hiding this comment

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

분리된 표현으로인해 복잡도가 올라갔고 그에 대해 전체적인 흐름의 그림이 잘 그려지지 않는다면,
다시 절차지향적으로 모아 보는것도 하나의 방법이 될 수 있을것 같아요.

스크린샷 2024-04-08 오후 9 52 24

저렇게 절차적으로 표현하고 나니,
저는 ResultView 의 기준으로 나누는게 크게 3분류로 나누어 보는게 어떨까? 라는 관점이 보이는것 같아요.

메소드가 분리된다면, 여기가 좀 애매해지네요.

        ResultView.showLottoQuantity(manualLottos, autoLottos);

manualLottos, autoLottos을 관리하는 객체가 하나로 나온다면 어떻게 변할지 궁금해지네요 🤔

    // Result 이름은 그냥 대충 지은것입니다.
    Result result = buyLotto();

이후 로직은 result 객체로 코드간의 대화를 이어가면 어떨까요?

Copy link

Choose a reason for hiding this comment

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

위는 저의 관점일 뿐입니다.

어떻게 코드를 정리해야하나요?

최고의 정리방법은 구현하면서 느꼈던 점을 상기시키면서 다시 구현하는거라고 개인적으론 생각합니다 🤔
물론 그과정은 지루하고 괴롭고 번거롭겠지만요. 😂

Copy link
Author

Choose a reason for hiding this comment

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

다시 구현한다면 어떻게 하면 좋을까요? 로또 생성에 대한 정보는 순차적으로 입력받는데 어떻게 객체지향적으로 개발할지 잘 모르겠습니다.


ResultView.showLottoQuantity(manualLottos, autoLottos);

Lottos allLottos = manualLottos.combine(autoLottos);
ResultView.showGeneratedLottos(allLottos);

return allLottos;
}

private Count getManualIssueCount(Budget budget) {
return InputView.retryableInputSelfIssueCount(budget);
}

private Lottos getManualIssuedLottos(Count count) {
return InputView.inputSelfIssueLottos(count);
}
private Lottos getAutoIssuedLottos(Budget budget) {
Lottos lottos = new Lottos(budget);
return lottos;
Comment on lines +45 to 46
Copy link

Choose a reason for hiding this comment

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

Suggested change
Lottos lottos = new Lottos(budget);
return lottos;
return new Lottos(budget);

불필요한 변수 선언은 하지 않는게 복잡도를 덜어낼수 있을것 같아요~

}

private Budget getBudget() {
Budget budget = InputView.inputBuyBudget();
ResultView.showLottoQuantity(budget.divide(Lotto.LOTTO_PRICE));
Budget budget = InputView.retryableInputBuyBudget();
return budget;
}

Expand Down
32 changes: 25 additions & 7 deletions src/main/java/lotto/domain/Budget.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
package lotto.domain;

public class Budget {
public class Budget{

private int value;
private int budget;

public Budget(int budget) {
this.value = budget;
validMinValue(budget);
this.budget = budget;
}

public int getValue() {
return value;
private void validMinValue(int budget) {
if(budget % 1000 != 0)
throw new IllegalArgumentException("100원 단위는 입력할 수 없습니다: " + budget);
}

public int divide(int lottoPrice) {
return value / lottoPrice;
public int purchasableQuantity(Price price) {
return price.divide(budget);
}

public boolean isEnoughToPay(Price price) {
return price.isEnough(budget);
}

public boolean isEnoughToPay(Price price, int count) {
return price.isEnough(budget, count);
}

public Budget spend(Price price) {
return new Budget(budget - price.getValue());
}

public Budget spend(Price price, Count issueCount) {
return new Budget(budget - price.multiple(issueCount));
}
}
47 changes: 47 additions & 0 deletions src/main/java/lotto/domain/Count.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package lotto.domain;

public class Count implements Comparable<Count>{

private int count;

public Count(int count) {
this(count, null);
}

public Count(int count, Budget budget) {
validPositiveValue(count);
validEnableCount(count, budget);
this.count = count;
}

private void validEnableCount(int count, Budget budget) {
if(budget == null) {
return;
}
if(!budget.isEnoughToPay(Price.LOTTO, count)){
throw new IllegalArgumentException("구매 가능 수량을 초과했습니다: " + count);
}
}

private void validPositiveValue(int count) {
if (count < 0)
throw new IllegalArgumentException("양수 값만 입력할 수 있습니다: " + count);
}

public int getCount() {
return count;
}

public boolean isPositive() {
return count > 0;
}

public Count decrease() {
return new Count(count - 1);
}

@Override
public int compareTo(Count that) {
return this.count - that.count;
}
}
49 changes: 39 additions & 10 deletions src/main/java/lotto/domain/Lotto.java
Original file line number Diff line number Diff line change
@@ -1,46 +1,75 @@
package lotto.domain;

import java.util.List;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

public class Lotto {
public class Lotto implements Comparable<Lotto>{

public static final int LOTTO_PRICE = 1000;
private List<LottoNumber> lotto;
private Set<LottoNumber> lotto;

public Lotto() {
this(LottoNumbers.issueNumbers());
}

public Lotto(List<LottoNumber> lotto) {
public Lotto(Set<LottoNumber> lotto) {
validEmpty(lotto);
validLottoSize(lotto);
this.lotto = lotto;
}

public static Lotto ofNumbers(List<Integer> lottoNumbers) {
public static Lotto ofNumbers(Set<Integer> lottoNumbers) {
validEmpty(lottoNumbers);
return new Lotto(lottoNumbers.stream().map(LottoNumber::new).collect(Collectors.toList()));
return new Lotto(getLottoNumbers(lottoNumbers));
}

private static void validEmpty(List<?> lotto) {
private static Set<LottoNumber> getLottoNumbers(Set<Integer> lottoNumbers) {
return lottoNumbers.stream()
.map(LottoNumber::new)
.collect(Collectors.toSet());
}

private static void validEmpty(Set<?> lotto) {
if (lotto == null || lotto.isEmpty()) {
throw new IllegalArgumentException("입력값이 없습니다");
}
}

public List<LottoNumber> getLotto() {
private static void validLottoSize(Set<?> lotto) {
if(lotto.size() != 6) {
throw new IllegalArgumentException("유효한 Lotto size가 아닙니다: " + lotto.size());
}
}

public Set<LottoNumber> getLotto() {
return lotto;
}

public int size() {
return lotto.size();
}

public boolean isContainBonus(LottoNumber bonus) {
return lotto.contains(bonus);
}

@Override
public int compareTo(Lotto that) {
Set<LottoNumber> compareSet = new HashSet<>(lotto);
compareSet.retainAll(that.lotto);
return compareSet.size();
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Lotto lotto1 = (Lotto) o;
return Objects.equals(lotto, lotto1.lotto);
}
Expand Down
8 changes: 3 additions & 5 deletions src/main/java/lotto/domain/LottoNumbers.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package lotto.domain;

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

Expand All @@ -18,11 +16,11 @@ private static List<LottoNumber> initialLottoRange() {
return lottoNumbers;
}

public static List<LottoNumber> issueNumbers() {
public static Set<LottoNumber> issueNumbers() {
List<LottoNumber> issueNumbers = new ArrayList<>(LOTTO_NUMBERS);
Collections.shuffle(issueNumbers);
issueNumbers = issueNumbers.subList(0, LOTTO_SIZE);
Collections.sort(issueNumbers);
return issueNumbers;
return new HashSet<>(issueNumbers);
}
}
21 changes: 20 additions & 1 deletion src/main/java/lotto/domain/Lottos.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.List;
import java.util.stream.Collectors;

import static lotto.domain.Price.LOTTO;

public class Lottos {

private List<Lotto> lottos;
Copy link

Choose a reason for hiding this comment

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

Suggested change
private List<Lotto> lottos;
private final List<Lotto> lottos;

재할당을 하지말라고 final을 붙여주는건 어떨까요?

Expand All @@ -12,15 +14,21 @@ public Lottos(Budget budget) {
this(generateLottosBy(budget));
}

public Lottos(Lotto lotto) {
this(List.of(lotto));
}

public Lottos(List<Lotto> lottos) {
this.lottos = lottos;
}

private static List<Lotto> generateLottosBy(Budget budget) {
List<Lotto> lottos = new ArrayList<>();

for (int i = 0; i < budget.divide(Lotto.LOTTO_PRICE); i++) {
if (budget.isEnoughToPay(LOTTO)) {
lottos.addAll(generateLottosBy(budget.spend(LOTTO)));
lottos.add(new Lotto());
return lottos;
}
return lottos;
Copy link

Choose a reason for hiding this comment

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

Collections.unmodifiableList

리턴해준 상태를 수정 불가로 해주면 어떨까요?

}
Expand All @@ -29,6 +37,10 @@ public List<Lotto> getLottos() {
return lottos;
}

public int size() {
return lottos.size();
}

public Statistics computeStatistic(WinLotto winLotto) {
return new Statistics(checkStatisticNumberMatch(winLotto));
}
Expand All @@ -45,4 +57,11 @@ private static Statistic getStatistic(WinLotto winLotto, Lotto lotto) {
winLotto.isContainBonus(lotto)
);
}

public Lottos combine(Lottos lottos) {
List<Lotto> newLottos = new ArrayList<>(this.lottos);
List<Lotto> combineLottos = lottos.getLottos();
newLottos.addAll(combineLottos);
return new Lottos(newLottos);
}
}
32 changes: 32 additions & 0 deletions src/main/java/lotto/domain/Price.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package lotto.domain;

public enum Price {
Copy link

Choose a reason for hiding this comment

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

enum을 사용한 이유가 궁금해요 🤔


LOTTO(1000);

private final int value;

Price(int value) {
this.value = value;
}

public int getValue() {
return value;
}

public int multiple(Count count) {
return count.getCount() * value;
}

public int divide(int budget) {
return budget / value;
}

public boolean isEnough(int budget) {
return value <= budget;
}

public boolean isEnough(int budget, int count) {
return value * count <= budget;
}
}
Loading