-
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
feature(step2): 로또(자동) 구현 #4160
Conversation
- 1000원당 1장 로또 갯수 계산 - 테스트 코드 추가 - LottoCountCalculator 추가
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.
2단계 잘 진행해주셨습니다~
몇가지 코멘트 남겨 놓았습니다~
확인 후 재요청 부탁드립니다!
|
||
public class LottoCountCalculator { | ||
|
||
private static final int PRICE_PER_TICKET = 1000; |
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.
Amount
라는 객체를 도입해보는 건 어떨까요?
객체지향과 TDD 관점에서 보면, static 메서드만 존재하는 클래스는 이번 과정에서 지양하는 편이 좋을것 같습니다~ 😄
private static final int LOTTO_MINIMUM_NUMBER = 1; | ||
private static final int LOTTO_MAXIMUM_NUMBER = 45; |
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.
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; |
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.
Rank가 가지는건 어떤가요?
private final List<Lotto> values; | ||
|
||
public Lottos(List<Lotto> values) { | ||
this.values = List.copyOf(values); |
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.
copy
와 같은 동작은 오히려 Lottos
를 사용하는 쪽에서 제어하거나, 정적 팩토리 메서드인 Lottos.copyOf(...)
형태로 제공하는 편이 더 자연스럽지 않을까요?
|
||
private void compareAll(Lottos lottos, Lotto winningLotto) { | ||
for (Lotto lotto : lottos.getValues()) { | ||
int matchCount = (int) lotto.getNumbers().stream() |
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.
값을 꺼내기보단 값을 가지고 있는 객체에게 시켜보면 어떨까요?
for (Lotto lotto : lottos.getValues()) {
Rank rank = lotto.match(winningLotto);
...
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.
2단계 잘진행주셨습니다!
몇가지 코멘트 남겨놓았어요~
다음 단계진행전에 확인 부탁드려요~
이만 merge
진행하겠습니다!
그럼 다음 단계도 화이팅입니다!
private final int value; | ||
|
||
public Amount(int value) { | ||
InputValidator.validatePurchaseAmount(value); |
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.
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())); |
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.
객체에게 메시지를 보내기를 좀 더 활용해본다면,
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()); |
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.
Lotto에 대한 의존성을 깊은 레이어까지 거져가는게 맞을지 고민이 되네요.
그래서 인자로 넘겨주는 방식이 더 나을까 생각 중입니다 🤔
관점 공유 정도로 봐주시면 감사하겠습니다~
lottoList.add(LottoNumberGenerator.generate(Lotto.MIN_NUMBER, Lotto.MAX_NUMBER));
int matchCount = lotto.countMatchWith(winningLotto); | ||
Rank rank = Rank.from(matchCount); | ||
|
||
if (rank.isWin()) { |
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.
2depth를 없애기위해서 다양한 시도를 해볼수있을것 같아요.
그중에 가장 쉬운 방법이 메소드 분리일것 같아요 🤔
Lotto numbers = LottoNumberGenerator.generate(); | ||
|
||
Set<Integer> unique = new HashSet<>(numbers.getNumbers()); | ||
|
||
assertThat(unique).hasSize(6); |
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.
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", |
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.
"900, 0",
는 특별한 케이스로 구분지어서 별도로 만들수 있을것 같아요
System.out.printf(MESSAGE_COUNT, rank.getMatchCount(), rank.getReward(), count); | ||
} | ||
|
||
String profitState = profitRate >= 1.0 ? PROFIT : LOSS; |
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.
관점에 따라 다르겠지만,
1.0
또한 도메인 로직으로 바라본다면,
isLoss
를 물어볼수있는 객체를 고민해볼것같아요 🤔
안녕하세요~! 오늘도 잘 부탁드립니다 😄