[로또] 최동근 미션 제출합니다.#445
Conversation
| public Integer count(Lotto lotto) { | ||
| return (int) IntStream.range(0, Rule.NUMBER_SIZE) | ||
| .filter(i -> lotto.contains(numbers.get(i))) | ||
| .count(); | ||
| } |
There was a problem hiding this comment.
저도 동의합니다! 메서드명을 조금 더 자세히 적으면 의도가 드러나 좋을 것 같아요!
There was a problem hiding this comment.
로또 생성자에서 꽤나 많은 책임이 있는 것 같아요! 외부에서 validate를 해서 주입하는 건 어떨까요?
| public static PurchaseAmount of(Integer value) { | ||
| return new PurchaseAmount(value); | ||
| } |
| private void validate(Lotto lotto, Bonus bonus) { | ||
| if (bonus.hasBonusNumber(lotto)) { | ||
| throw new IllegalArgumentException(ErrorMessage.BONUS_DUPLICATE.getMessage()); | ||
| } | ||
| } |
There was a problem hiding this comment.
bonus.hasBonusNumber(lotto) 라는 문장은
bonus가 lotto라는 BonusNumber를 가지는가? 라고 읽힙니다!
| public WinningLotto getWinningLotto(InputView inputView, OutputView outputView) { | ||
| Lotto lotto = getWinningNumbers(inputView, outputView); | ||
| while (true) { | ||
| try { | ||
| Bonus bonus = getBonusNumber(inputView, outputView); | ||
| return new WinningLotto(lotto, bonus); | ||
| } catch (IllegalArgumentException exception) { | ||
| outputView.printErrorMessage(exception); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private Lotto getWinningNumbers(InputView inputView, OutputView outputView) { | ||
| while (true) { | ||
| try { | ||
| return readWinningNumbers(inputView); | ||
| } catch (IllegalArgumentException exception) { | ||
| outputView.printErrorMessage(exception); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
요구사항에 맞춰서 보너스 번호/당첨 번호 입력받는 로직을 분리하신 점이 좋은 것 같아요!
(저도 이렇게 했어야 했는데 ㅠ.ㅠ)
배워갑니다!
There was a problem hiding this comment.
InputController가 거의 모든 메소드마다 inputView와 outputView를 매개변수로 가지네요.
조금 번거로워 보이는데 LottoController로부터 InputController를 분리하신 이유가 있을까요?
inputView와 outputView를 주입을 받아서 사용하지 않으신 이유 또한 궁금합니다!
There was a problem hiding this comment.
로또 컨트롤러에서 인풋컨트롤러를 분리한 이유는 예외 시 다시 입력받는 부분을 따로 처리해주고 싶었기 때문입니다!
그리고 뷰들을 매개변수로 가지고 있는 이유는, 사실 처음에 인풋컨트롤러를 만들었을때 인풋뷰, 아웃풋뷰 모두 인풋컨트롤러의 인스턴스 변수였는데, 그렇게 되다보니 로또 컨트롤러와 차이점을 잘 못느껴 구분하고자 매개변수로 받는 방법을 택했습니다!
|
안녕하세요 동근님! 저번주에 이어서 이번주에도 방문하였습니다...ㅋㅋ |
| } | ||
|
|
||
| public PurchaseAmount getPurchaseAmount(InputView inputView, OutputView outputView) { | ||
| while (true) { |
There was a problem hiding this comment.
예외가 발생했을 때 메시지를 출력하고 입력을 다시 받는 로직을 재귀로 해결했는데 성능(메모리)관련해서 걱정이 있었는데,
반복문으로 깔끔하게 해결하셨네요..! 이런 방법이 있었네요! 배워갑니다! 👍
| public WinningLotto getWinningLotto(InputView inputView, OutputView outputView) { | ||
| Lotto lotto = getWinningNumbers(inputView, outputView); | ||
| while (true) { | ||
| try { | ||
| Bonus bonus = getBonusNumber(inputView, outputView); | ||
| return new WinningLotto(lotto, bonus); | ||
| } catch (IllegalArgumentException exception) { | ||
| outputView.printErrorMessage(exception); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private Lotto getWinningNumbers(InputView inputView, OutputView outputView) { | ||
| while (true) { | ||
| try { | ||
| return readWinningNumbers(inputView); | ||
| } catch (IllegalArgumentException exception) { | ||
| outputView.printErrorMessage(exception); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
요구사항에 맞춰서 보너스 번호/당첨 번호 입력받는 로직을 분리하신 점이 좋은 것 같아요!
(저도 이렇게 했어야 했는데 ㅠ.ㅠ)
배워갑니다!
There was a problem hiding this comment.
InputController로 따로 분리하니 로직도 깔끔하고, 가독성도 좋네요..!!! 배워갑니다! 👍
There was a problem hiding this comment.
미션에서 문자열에서 정수로 변환하는 일이 잦았는데,
StringToInteger 클래스를 통해 변환도 하고, 검증도 하네요..! 좋은 것 같습니다! 👍
There was a problem hiding this comment.
엇 이야기를 들어보니까 변환도 하고 검증도 하는 두가지 일을 하고 있는거 같군요(?)! ㅋㅋㅋ👀
| public Integer count(Lotto lotto) { | ||
| return (int) IntStream.range(0, Rule.NUMBER_SIZE) | ||
| .filter(i -> lotto.contains(numbers.get(i))) | ||
| .count(); | ||
| } |
There was a problem hiding this comment.
저도 동의합니다! 메서드명을 조금 더 자세히 적으면 의도가 드러나 좋을 것 같아요!
There was a problem hiding this comment.
LottoIssuer라는 클래스를 따로 만들어서 적용하니 더 깔끔하고 가독성이 좋은 것 같아요..!!
클래스가 하나의 역할을 한다는 원칙에 잘 맞는 것 같습니다! 👍
jinkshower
left a comment
There was a problem hiding this comment.
깔끔한 코드 잘 보고 갑니다
궁금하고 배울점이 많아서 그부분에 코멘트 남겨두고 가봅니다~
| * [x] 구입금액이 1000 미만인 경우 | ||
| * [x] 구입금액이 1000으로 나누어 떨어지지 않는 경우 | ||
| * [x] 구입금액이 100,000을 초과하는 경우 | ||
| * 복권 및 복권기금법 1인당 구매한도 초과 위반 |
| outputView.printWinningStatistics(result); | ||
| Revenue revenue = calculate(winners, amount); | ||
| outputView.printTotalReturn(revenue); | ||
| } |
|
|
||
| public Integer exchangeLottoTicket() { | ||
| return amount / Rule.MONEY_UNIT; | ||
| } |
There was a problem hiding this comment.
저도 "티켓의 개수를 반환한다"라는 의미가 들어나면 좋을 것 같아요!
| } | ||
| } | ||
| return null; | ||
| } |
There was a problem hiding this comment.
stream()을 이용하면 indent를 줄일수 있지 않을까요? 저는
https://techblog.woowahan.com/2527/
여기서 본 걸 적용해봤습니다
| result.put(rank, result.getOrDefault(rank, 0) + 1); | ||
| } | ||
| return new Result(result); | ||
| } |
There was a problem hiding this comment.
enumMap.... getOrDefault... JCF에 대한 학습을 좀 더 하고 싶어지네요 감사해요
|
|
||
| public static LottoIssuer of(PurchaseAmount purchaseAmount) { | ||
| return new LottoIssuer(purchaseAmount.exchangeLottoTicket(), new LottoGenerator()); | ||
| } |
There was a problem hiding this comment.
purchaseAmount.exchangeLottoTicket() 를 생성자를 호출하며 선언하기 보다 이미 반환된 int 값을 넘겨주는 것이 어떨까요!
| public static final String BOUGHT_LOTTO_AMOUNT_MESSAGE_FORMAT = "%d개를 구매했습니다.%n"; | ||
| public static final String RANK_PREFIX = String.format("당첨 통계%n" + "---"); | ||
| public static final String PRIZE_MESSAGE_FORMAT = "%s (%s원) - %d개"; | ||
| public static final String PRIZE_NUMBER_FORMAT = "###,###"; |
There was a problem hiding this comment.
저도 처음에 이렇게 썼는데 이렇게 하면 수익률이 0일때 0.0%로 안나오더라구요. Decimal Format에서 #대신 0을 쓰면 수가 없을때 0을 채워준다고 합니다. 그래서 저는 "#,##0.0%" <- 요렇게 썼어요
| Arguments.of(List.of(10, 2, 3, 45, 5, 7), true) | ||
| ); | ||
| } | ||
| } |
| StringToInteger converter = new StringToInteger(); | ||
| assertThat(converter.convert(value)).isEqualTo(Integer.valueOf(value.trim())); | ||
| } | ||
| } |
There was a problem hiding this comment.
반복되는 객체 생성은 @beforeeach로 줄일 수가 있다네요!
| public String toString() { | ||
| return numbers.toString(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Integer , Boolean을 int boolean대신 쓰는 이유가 궁금합니다 (정말)
| class RankTest { | ||
|
|
||
| private static final Lotto winningLotto = new Lotto(List.of(3, 14, 15, 9, 2, 6)); | ||
| private static final Bonus bonusNumber = new Bonus(5); |
There was a problem hiding this comment.
이렇게 따로 두면 되는데 전 이걸 다~~ 썼네요. 하하하하 배워갑니다
| for (Rank rank : ranks) { | ||
| result.put(rank, result.getOrDefault(rank, 0) + 1); | ||
| } | ||
| return new Result(result); |
| public static Rank from(Integer match, Boolean isSameBonus) { | ||
| if (SECOND.match.equals(match) && SECOND.isSameBonus.equals(isSameBonus)) { | ||
| return SECOND; | ||
| } | ||
| for (Rank prize : Rank.values()) { | ||
| if (prize.match.equals(match)) { | ||
| return prize; | ||
| } | ||
| } | ||
| return null; | ||
| } |
There was a problem hiding this comment.
if 문 3개로 코딩해서 뭔가 고쳐보고 싶었는데 이렇게도 할 수 있군요 배워갑니다!
hyeonji1220
left a comment
There was a problem hiding this comment.
역시 테스트 코드 장인 동근님👏👏 오늘도 꼼꼼한 테스트에 놀라면서 갑니다!
수고 많으셨어요!
| } | ||
|
|
||
| private Lotto readWinningNumbers(InputView inputView) { | ||
| List<Integer> numbers = Arrays.stream(inputView.readWinningNumbers().split(NUMBER_SEPARATOR)) |
There was a problem hiding this comment.
split으로 하고 넘어갈 경우 1,2,3,4,5,6,,,,, 이런 입력에 대해서는 예외를 던지지 않는데
이러한 형식은 예외처리가 필요없다고 생각하시는지 궁금합니다!
There was a problem hiding this comment.
split을 하고 ,,, 라는 부분은 로또로 변환하며 !NUMERIC_PATTERN.matcher(source.trim()).matches() 에서 걸리게 되는 점이 맞을까요??
split한 개수가 6이 맞는지도 검증이 있으면 좋을 것 같습니다!
There was a problem hiding this comment.
split한 개수가 6개가 맞는지에 대한 검증은 아래 Lotto 객체를 생성하고 그 곳에서 수행됩니다!
1,2,3,4,5,6,,,,, 오 이부분은 놓쳤네요
사실 1,2,3,4,5,6, 처럼 마지막에 "," 가 있는 경우는 예외 처리 하지 않았는데 여러개가 올때는 필요해보이네요👍
| } | ||
|
|
||
| private List<Lotto> buyLotto(PurchaseAmount amount) { | ||
| LottoIssuer lottoIssuer = LottoIssuer.of(amount); |
There was a problem hiding this comment.
이렇게 하면 LottoIssuer 객체가 PurchaseAmount 객체에 의존성을 갖게될 것 같습니다!
불필요한 의존관계는 유지 보수를 어렵게한다고 생각해서 특별한 이유가 없다면 의존관계를 최소화하기 위해
여기서 LottoIssuer.of(purchaseAmount.exchangeLottoTicket()) 이렇게 넣어줘도 좋을 것 같아요!
| } | ||
|
|
||
| private String convertPrizeFormat(Integer prize) { | ||
| return new DecimalFormat(PRIZE_NUMBER_FORMAT).format(prize); |
There was a problem hiding this comment.
돈 관련 숫자 처리에 DecimalFormat를 쓰는 방법이 종종 보이네요! 덕분에 다시 알아갑니다😋
| Collections.nCopies(second, SECOND), | ||
| Collections.nCopies(third, THIRD), | ||
| Collections.nCopies(fourth, FOURTH), | ||
| Collections.nCopies(fifth, FIFTH) |
There was a problem hiding this comment.
nCopies라는 메소드가 있었군요! 동근님의 테스트 코드에서는 어떤 새로운 메소드를 발견하게 될까 기대하면서 보게됩니다ㅎㅎ
kyeoungchan
left a comment
There was a problem hiding this comment.
도메인과 서비스별로 책임 분리를 엄청 잘해주셨네요! 많이 배우고 갑니다
| protected String readLine(String message) { | ||
| System.out.println(message); | ||
| String input = Console.readLine(); | ||
| System.out.println(); |
There was a problem hiding this comment.
이건 빼도 똑같이 빈줄이 나와서 입력 예시랑 같은 형태로 나오지 않을까요?
| @@ -0,0 +1,14 @@ | |||
| package lotto.constant; | |||
|
|
|||
| public class Rule { | |||
There was a problem hiding this comment.
ErrorMessage는 Enum인데 Rule은 일반 클래스로 작성하신 차이를 두는 기준이 있으실까요?
There was a problem hiding this comment.
enum 사용시 값을 사용하려면 Rule.MIN_NUMBER.getValue() 이런 식으로 사용하게 되는데 정수관련된 값들은 뒤에 getValue 메서드를 사용하지 않고 바로 값을 가져오고 싶어서 사용했습니다!
| @@ -0,0 +1,5 @@ | |||
| package lotto.service; | |||
|
|
|||
| public interface Calculator<T> { | |||
There was a problem hiding this comment.
인터페이스를 사용하여 추상화하는 편을 좋아하는거 같습니다 ㅎㅎ
dgnppr
left a comment
There was a problem hiding this comment.
전반적인 코드 구조가 깔끔해서 읽기 좋네요!
이번주도 고생많으셨습니다 ㅎㅎ
| outputView.printWinningStatistics(result); | ||
| Revenue revenue = calculate(winners, amount); | ||
| outputView.printTotalReturn(revenue); | ||
| } |
| throw new IllegalArgumentException(ErrorMessage.INVALID_TYPE.getMessage(), e); | ||
| } | ||
| } | ||
| } |
| public Integer count(Lotto lotto) { | ||
| return (int) IntStream.range(0, Rule.NUMBER_SIZE) | ||
| .filter(i -> lotto.contains(numbers.get(i))) | ||
| .count(); | ||
| } |
There was a problem hiding this comment.
로또 생성자에서 꽤나 많은 책임이 있는 것 같아요! 외부에서 validate를 해서 주입하는 건 어떨까요?
| void printTotalReturn(Revenue revenue); | ||
|
|
||
| void printErrorMessage(Exception exception); | ||
| } |
There was a problem hiding this comment.
OutputView를 인터페이스로 도입한 이유를 알 수 있을까요? 구현체가 하나이고, 자주 변경되는 기능이 아닐 것 같아서요. 모킹 테스트를 위함인가요?
|
|
||
| INVALID_TYPE("잘못된 타입입니다"), | ||
| INVALID_LENGTH("잘못된 길이의 당첨 번호입니다."), | ||
| INVALID_LOTTO_RANGE("잘못된 범위의 로또 숫자입니다."), |
There was a problem hiding this comment.
String.format으로 로또의 범위를 구체적으로 알려줄 수 있을것 같아요!
There was a problem hiding this comment.
정답은 없겠지만 이번에는 예외 메시지를 좀 폭넓게 사용하여 더 많은 곳에서 같은 예외 메시지를 던져보고 싶었습니다!
| outputView.printErrorMessage(exception); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
코드리뷰를 보다보니, try-catch에 대해서도 한번 더 분리를 할 수 있는 점을 알았어요! 예외 핸들링을 통해 try-catch를 분리하는 것은 어떻게 생각하세요?
| } | ||
|
|
||
| private Lotto readWinningNumbers(InputView inputView) { | ||
| List<Integer> numbers = Arrays.stream(inputView.readWinningNumbers().split(NUMBER_SEPARATOR)) |
There was a problem hiding this comment.
split을 하고 ,,, 라는 부분은 로또로 변환하며 !NUMERIC_PATTERN.matcher(source.trim()).matches() 에서 걸리게 되는 점이 맞을까요??
split한 개수가 6이 맞는지도 검증이 있으면 좋을 것 같습니다!
|
|
||
| public Integer exchangeLottoTicket() { | ||
| return amount / Rule.MONEY_UNIT; | ||
| } |
There was a problem hiding this comment.
저도 "티켓의 개수를 반환한다"라는 의미가 들어나면 좋을 것 같아요!
|
|
||
| public static LottoIssuer of(PurchaseAmount purchaseAmount) { | ||
| return new LottoIssuer(purchaseAmount.exchangeLottoTicket(), new LottoGenerator()); | ||
| } |
There was a problem hiding this comment.
purchaseAmount.exchangeLottoTicket() 를 생성자를 호출하며 선언하기 보다 이미 반환된 int 값을 넘겨주는 것이 어떨까요!
| void printTotalReturn(Revenue revenue); | ||
|
|
||
| void printErrorMessage(Exception exception); | ||
| } |
ssuzyn
left a comment
There was a problem hiding this comment.
하나의 클래스가 하나의 역할을 할 수 있도록 분리시킨 노력이 보입니다 !! 잘 배우고 갑니다
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| public class InputController { |
There was a problem hiding this comment.
입력받는 부분을 따로 Controller로 분리한 것이 인상깊습니다 !!
| private void validateLength(List<Integer> numbers) { | ||
| if (numbers.size() != Rule.NUMBER_SIZE) { | ||
| throw new IllegalArgumentException(ErrorMessage.INVALID_LENGTH.getMessage()); | ||
| } | ||
| } | ||
|
|
||
| private void validateDuplicate(List<Integer> numbers) { | ||
| if (Set.copyOf(numbers).size() != Rule.NUMBER_SIZE) { | ||
| throw new IllegalArgumentException(ErrorMessage.LOTTO_DUPLICATE.getMessage()); | ||
| } | ||
| } | ||
|
|
||
| private void validateRange(List<Integer> numbers) { | ||
| if (numbers.stream() | ||
| .anyMatch(number -> number < Rule.MIN_NUMBER || number > Rule.MAX_NUMBER)) { | ||
| throw new IllegalArgumentException(ErrorMessage.INVALID_LOTTO_RANGE.getMessage()); | ||
| } | ||
| } |
There was a problem hiding this comment.
로또 번호를 검증하는 부분은 따로 분리해서 관리하는 것이 어떨까요??
Lotto 클래스에서 너무 많은 역할이 있는 것 같아요 !!
GIVEN53
left a comment
There was a problem hiding this comment.
책임 분리에 신경을 많이 쓰신게 느껴지네요 코드 재밌게 읽었습니다
마지막 4주차도 화이팅!
|
|
||
| public class Bonus { | ||
|
|
||
| private final Integer number; |
| if (SECOND.match.equals(match) && SECOND.isSameBonus.equals(isSameBonus)) { | ||
| return SECOND; | ||
| } | ||
| for (Rank prize : Rank.values()) { |
There was a problem hiding this comment.
values()는 호출할 때마다 enum의 모든 객체를 배열로 생성해서 리턴해요 반복적으로 사용되는 만큼 static 변수로 초기화해서 재사용하면 최적화할 수 있을 것 같아요
| public static final int MAX_NUMBER = 45; | ||
| public static final int NUMBER_SIZE = 6; | ||
| public static final int MIN_MONEY = 1_000; | ||
| public static final int MAX_MONEY = 100_000; |
| @Override | ||
| public Integer convert(String source) { | ||
| validate(source); | ||
| return Integer.valueOf(source.trim()); |
There was a problem hiding this comment.
validateRange()에 성공하면 int 형변환을 두 번 수행하게 되는데 한 번으로 줄이면 좋을 것 같아요
There was a problem hiding this comment.
검증하는 메서드 따로, 형변환 하는 메서드 따로 분리하기 위해 그런식으로 사용하긴 했습니다만 중복이라는 점이 걸리긴 하네요
| return prize; | ||
| } | ||
| } | ||
| return null; |
Hanjaemo
left a comment
There was a problem hiding this comment.
3주차 미션 고생하셨습니다! 남은 일주일도 화이팅해서 꼭 합격하시길 기원합니다🔥🔥
| } | ||
|
|
||
| private void validateLength(List<Integer> numbers) { | ||
| if (numbers.size() != Rule.NUMBER_SIZE) { |
There was a problem hiding this comment.
메서드(validateLength)와 오류 메시지(INVALID_LENGTH)의 경우 length라는 네이밍을 사용했는데 상수의 경우 NUMBER_SIZE라고 지으신 이유가 있을까요?
저는 통일하는 것이 좋을 것 같다고 느껴집니다!
| } | ||
|
|
||
| private void validateDuplicate(List<Integer> numbers) { | ||
| if (Set.copyOf(numbers).size() != Rule.NUMBER_SIZE) { |
There was a problem hiding this comment.
이 부분 머리가 띵하네요,,
항상 Set<> set = new HashSet<> 이렇게 생성해서 검증했는데, copyOf를 사용하면 되는군요!!!
| } | ||
|
|
||
| public Integer count(Lotto lotto) { | ||
| return (int) IntStream.range(0, Rule.NUMBER_SIZE) |
There was a problem hiding this comment.
이 메서드는 당첨 번호랑 현재 로또 번호가 몇개 겹치는지 세는 메서드입니다! 아래에도 의미가 부족하다는 코멘트를 여럿 받은거 보니 메서드 명을 좀 더 의미 있게 짓거나 스트림 연산 메서드를 분리해야 겠네요 ㅎㅎ
| return prize; | ||
| } | ||
| } | ||
| return null; |
| @Override | ||
| public String toString() { | ||
| return "PurchaseAmount{" + | ||
| "amount=" + amount + | ||
| "}"; | ||
| } |
There was a problem hiding this comment.
모든 클래스에 toString()을 재정의 하시는 이유가 궁금합니다!
There was a problem hiding this comment.
이펙티브 자바를 읽다가 모든 클래스에서 toString() 을 재정의하라는 키워드가 있어서 적용해보았습니다!
이유는 toString 메서드의 용도는 로깅을 찍기위한 메서드로 언제 어디서 사용될 지 모르기에 해당 객체가 가진 정보를 출력할 의무를 가지고(?) 재정의 하였습니다
|
|
||
| public record Revenue(Double number) { | ||
|
|
||
| private static final String ROUND_FORMAT = "%.1f"; |
There was a problem hiding this comment.
"%.1f"는 출력을 담당하는 객체에서 관리하는 것은 어떨까요?
소수점 출력 형식을 변경하라는 요구 사항이 �왔을 때 저는 이 모델 객체보다 출력 로직을 먼저 볼 것 같아요!
| @@ -0,0 +1,18 @@ | |||
| package lotto.service; | |||
There was a problem hiding this comment.
LottoGenerator, LottoIssuer, PrizeCalculator클래스를 모델이 아닌 서비스 패키지에 놓으신 이유가 있을까요?
|
|
||
| public class PurchaseAmount { | ||
|
|
||
| private final Integer amount; |
There was a problem hiding this comment.
래퍼 클래스를 사용하면 null을 허용할텐데, 모든 필드를 래퍼 클래스로 사용하신 이유가 궁금합니다!
| public static Rank from(Integer match, Boolean isSameBonus) { | ||
| if (SECOND.match.equals(match) && SECOND.isSameBonus.equals(isSameBonus)) { | ||
| return SECOND; | ||
| } | ||
| for (Rank prize : Rank.values()) { | ||
| if (prize.match.equals(match)) { | ||
| return prize; | ||
| } | ||
| } | ||
| return null; |
There was a problem hiding this comment.
enum에 람다식을 사용할 수 있더라구요??
이를 활용하면 코드가 훨씬 간결해지실 것 같아요!
|
|
||
| private final Integer match; | ||
| private final Boolean isSameBonus; | ||
| private final Integer prize; |
There was a problem hiding this comment.
상금은 정수의 최댓값을 충분히 넘길 수도 있을 것 같아요! Long을 사용해보시는 건 어떨까요?
| } | ||
|
|
||
| private void validateType(String source) { | ||
| if (source == null || !NUMERIC_PATTERN.matcher(source.trim()).matches()) { |
There was a problem hiding this comment.
개인적으로 이부분은 메서드로 한번 더 분리하는 게 더 가독성이 좋을 것 같습니다!
| FOURTH(4, false, 50_000, "4개 일치"), | ||
| THIRD(5, false, 1_500_000, "5개 일치"), | ||
| SECOND(5, true, 30_000_000, "5개 일치, 보너스 볼 일치"), | ||
| FIRST(6, false, 2_000_000_000, "6개 일치"); |
There was a problem hiding this comment.
모델에서 메세지에 대한 부분까지 가지고 있으면
메세지 내용이 변경될 때 모델 부분을 수정해야되는 문제점을 가지고 있을 것 같습니다
| Arguments.of(List.of(10, 2, 3, 45, 5, 7), true) | ||
| ); | ||
| } | ||
| } |
ChoiWonYu
left a comment
There was a problem hiding this comment.
다른 분들이 제가 궁금한 부분들을 모두 말씀해 주셔서 코멘트가 적네요...!
코드 잘보고 갑니다 고생하셨습니다! 😁
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| public class InputController { |
There was a problem hiding this comment.
입력에 대한 처리를 이 객체에서 하는 것 같은데
굳이 inputView를 LottoController에 주입하고 여기에 전달해 주는 이유가 궁금합니다..!
There was a problem hiding this comment.
로또 컨트롤러가 메인컨트롤러 느낌이고, 인풋컨트롤러는 정상적인 입력을 받을때까지 입력받는 역할을 담당하고 있는 컨트롤러입니다!
사실 처음에 인풋컨트롤러를 만들었을때 인풋뷰, 아웃풋뷰 모두 인풋컨트롤러의 인스턴스 변수였는데, 그렇게 되다보니 로또 컨트롤러와 차이점을 잘 못느껴 구분하고자 매개변수로 받는 방법을 택했는데, 적으면서 다시 생각해보니 아예 inputView를 로또 컨트롤러에서 가지고 있을 필요가 없을거 같군요 ㅎㅎ👍
| private final Integer amount; | ||
|
|
||
| private PurchaseAmount(Integer amount) { | ||
| validate(amount); |
There was a problem hiding this comment.
특정 유효성 검사 로직을 정적 팩토리 메서드가 아닌 생성자에서 하신 이유가 궁금합니다!
There was a problem hiding this comment.
그것도 방법이겠군요! static 메서드를 사용할때에는 항상 조심하면서 사용하는 편이라 정적 팩토리 메서드 내부 대신 객체 생성 후 사용하는 방식으로 했습니다!
|
|
||
| public static Rank from(Integer match, Boolean isSameBonus) { | ||
| if (SECOND.match.equals(match) && SECOND.isSameBonus.equals(isSameBonus)) { | ||
| return SECOND; |
There was a problem hiding this comment.
이렇게 처리되면 보너스 번호 조건을 가지는 rank가 변할 때마다 수정이 되어야 하겠네요! rank의 조건만 변경해줘도 수정 없이 반영되도록 할 수 있을 것 같습니다..!
위 사항들을 지키며 미션을 진행하였습니다.