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

feature(step2): 로또(자동) 구현 #4160

Merged
merged 18 commits into from
Apr 8, 2025

Conversation

LeeJin0527
Copy link

안녕하세요~! 오늘도 잘 부탁드립니다 😄

@LeeJin0527 LeeJin0527 changed the base branch from master to leejin0527 April 6, 2025 04:03
Copy link

@wooobo wooobo left a comment

Choose a reason for hiding this comment

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

2단계 잘 진행해주셨습니다~

몇가지 코멘트 남겨 놓았습니다~
확인 후 재요청 부탁드립니다!


public class LottoCountCalculator {

private static final int PRICE_PER_TICKET = 1000;
Copy link

Choose a reason for hiding this comment

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

Amount라는 객체를 도입해보는 건 어떨까요?
객체지향과 TDD 관점에서 보면, static 메서드만 존재하는 클래스는 이번 과정에서 지양하는 편이 좋을것 같습니다~ 😄

Comment on lines 10 to 11
private static final int LOTTO_MINIMUM_NUMBER = 1;
private static final int LOTTO_MAXIMUM_NUMBER = 45;
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 static final int LOTTO_MINIMUM_NUMBER = 1;
private static final int LOTTO_MAXIMUM_NUMBER = 45;
private static final int LOTTO_MINIMUM_NUMBER = 1;
private static final int LOTTO_MAXIMUM_NUMBER = 45;

이 상수는 이미 Lotto 객체가 책임지고 있으니, 중복해서 책임을 갖기보다는 한 곳에서만 관리하는 편이 더 좋지 않을까요?


public class LottoResult {

private static final int NO_MATCH = 0;
Copy link

Choose a reason for hiding this comment

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

Rank가 가지는건 어떤가요?

private final List<Lotto> values;

public Lottos(List<Lotto> values) {
this.values = List.copyOf(values);
Copy link

Choose a reason for hiding this comment

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

copy와 같은 동작은 오히려 Lottos를 사용하는 쪽에서 제어하거나, 정적 팩토리 메서드인 Lottos.copyOf(...) 형태로 제공하는 편이 더 자연스럽지 않을까요?


private void compareAll(Lottos lottos, Lotto winningLotto) {
for (Lotto lotto : lottos.getValues()) {
int matchCount = (int) lotto.getNumbers().stream()
Copy link

Choose a reason for hiding this comment

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

값을 꺼내기보단 값을 가지고 있는 객체에게 시켜보면 어떨까요?

for (Lotto lotto : lottos.getValues()) {
    Rank rank = lotto.match(winningLotto);
     ...

Copy link

@wooobo wooobo left a comment

Choose a reason for hiding this comment

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

2단계 잘진행주셨습니다!

몇가지 코멘트 남겨놓았어요~
다음 단계진행전에 확인 부탁드려요~

이만 merge진행하겠습니다!
그럼 다음 단계도 화이팅입니다!

private final int value;

public Amount(int value) {
InputValidator.validatePurchaseAmount(value);
Copy link

Choose a reason for hiding this comment

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

InputValidator가 꼭 필요한지 의문이드는데요!

Amount 도메인 책임이 아닐지 생각이들어서요!

  • 빈값일수없다
  • 0이상이어야한다라는

Lottos lottos = buyLottos(count);
ResultView.printPurchasedLotto(lottos);

Lotto winningLotto = InputView.inputWinningNumbers();
LottoResult result = new LottoResult(lottos, winningLotto);

ResultView.printStatistics(result.getResults(), result.calculateProfitRate(amount));
ResultView.printStatistics(result.getResults(), result.calculateProfitRate(amount.getValue()));
Copy link

Choose a reason for hiding this comment

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

객체에게 메시지를 보내기를 좀 더 활용해본다면,

public class LottoResult {
    ....
    public Amount calculateProfitRate(Amount amount) {
        return amount.multiply(getTotalReward());
    }

이런식을 생각해볼수도 있을것 같아요!

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

for (int i = 0; i < count; i++) {
lottoList.add(LottoNumberGenerator.generate());
Copy link

Choose a reason for hiding this comment

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

Lotto에 대한 의존성을 깊은 레이어까지 거져가는게 맞을지 고민이 되네요.
그래서 인자로 넘겨주는 방식이 더 나을까 생각 중입니다 🤔
관점 공유 정도로 봐주시면 감사하겠습니다~

lottoList.add(LottoNumberGenerator.generate(Lotto.MIN_NUMBER, Lotto.MAX_NUMBER));

int matchCount = lotto.countMatchWith(winningLotto);
Rank rank = Rank.from(matchCount);

if (rank.isWin()) {
Copy link

Choose a reason for hiding this comment

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

2depth를 없애기위해서 다양한 시도를 해볼수있을것 같아요.
그중에 가장 쉬운 방법이 메소드 분리일것 같아요 🤔

Comment on lines +23 to +27
Lotto numbers = LottoNumberGenerator.generate();

Set<Integer> unique = new HashSet<>(numbers.getNumbers());

assertThat(unique).hasSize(6);
Copy link

Choose a reason for hiding this comment

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

Suggested change
Lotto numbers = LottoNumberGenerator.generate();
Set<Integer> unique = new HashSet<>(numbers.getNumbers());
assertThat(unique).hasSize(6);
assertThatThrownBy(() -> LottoNumberGenerator.generate(100, 200))

저같은 경우 TDD를 통해서 어떤 메시지(인자 or 메소드명)을 전달할지 작은 범위에서 부터 테스트하였다면
이러한 테스트를 만들었을것 같아요 🤔

RepeatedTest테스트가 필요한 경우가 있지만, 지금 같은 경우에 운좋게 RepeatedTest를 모두 통과하는 경우의 수가 발생한다면 정말 좋은 테스트일까요?

@DisplayName("금액에 따른 로또 갯수를 계산한다.")
@ParameterizedTest
@CsvSource({
"900, 0",
Copy link

Choose a reason for hiding this comment

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

"900, 0",는 특별한 케이스로 구분지어서 별도로 만들수 있을것 같아요

System.out.printf(MESSAGE_COUNT, rank.getMatchCount(), rank.getReward(), count);
}

String profitState = profitRate >= 1.0 ? PROFIT : LOSS;
Copy link

Choose a reason for hiding this comment

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

관점에 따라 다르겠지만,
1.0또한 도메인 로직으로 바라본다면,
isLoss를 물어볼수있는 객체를 고민해볼것같아요 🤔

@wooobo wooobo merged commit b4b51a1 into next-step:leejin0527 Apr 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants