-
Notifications
You must be signed in to change notification settings - Fork 0
Java lotto game 이현 #1
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
base: main
Are you sure you want to change the base?
The head ref may contain hidden characters: "java_lotto_game_\uC774\uD604"
Conversation
구매 금액의 단위가 1000으로 떨어지지 않는다고 가정하면 (ex: 8001) 구매한 로또 개수 * 1000의 값을 사용해야 한다.
로또 숫자 범위는 1~45이기 때문에 WinningNumber와 BonusNumber 둘 다 입력 받을 때 체크해야 한다.
효율적인 방법으로 수정
| private WinningLotto winningLotto; | ||
| private Lotto winningNumberList; | ||
| private int bonusNumber; | ||
| private int lottoCount; | ||
|
|
||
| public void run() { | ||
| input(); | ||
| printResult(); | ||
| } | ||
|
|
||
| private void input() { | ||
| System.out.println("구입 금액을 입력해주세요."); | ||
| while (inputPrice() == InputType.INVALID) | ||
| ; | ||
|
|
||
| System.out.println("지난 주 당첨번호를 입력해 주세요."); | ||
| while (inputWinningNumber() == InputType.INVALID) | ||
| ; | ||
|
|
||
| System.out.println("보너스 볼을 입력해 주세요."); | ||
| while (inputBonusNumber() == InputType.INVALID) | ||
| ; | ||
|
|
||
| winningLotto = new WinningLotto(winningNumberList, bonusNumber); |
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.
winningLotto는 winningNumberList, bonusNumber 값으로 인스턴스를 생성하는데,
class의 인스턴스 변수(winningNumberList, bonusNumber)와 동일한 값을 가지게 되어 비효율적이라고 생각합니다.
input() 메서드에서 해결하고 싶은데, 어떻게 하면 좋을지 의견을 얻어보고 싶습니다..!
winningNumberList가 필요하다면, winningLotto.getLotto()와 같은 방법을 사용하는 것이 더 깔끔하겠네요.
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.
아 이런 문제를 말씀하셨던 것이군요!
그러게요 🤔... 어렵네요...
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 void printRankMap(HashMap<Integer, Integer> rankMap) { | ||
| Arrays.stream(Rank.values()) | ||
| .forEach(rankObj -> { | ||
| Optional<Integer> priceCount = Optional.ofNullable(rankMap.get(rankObj.getMatch())); |
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.
Optional은 return으로 사용을 권고하고 있는데, 3항 연산자를 쓰는 것은 어떻게 생각하는지 궁금합니다!
https://johngrib.github.io/wiki/java/optional/
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.
맞는 답변이 될 지는 모르겠지만, 올해 우테코 로또 게임 요구사항에서는 3항 연산자 사용을 금하고 있네요! 동일한 문제입니다.
https://github.com/woowacourse-precourse/java-lotto
아무래도 가독성? 측면에서 안좋다고 보아서 금하는 것 같아요
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.
아하.. 알겠습니다 :)
gusah009
left a comment
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.
밤새서 만들었다니... ㄷㄷ 수고 많으셨습니다!!
GamePlayer 클래스가 너무 큰 느낌입니다. UI를 구성하는 출력 파트만 따로 분리하는 것도 좋을 것 같습니다!!
| public static void checkNumeric(String strNumber) { | ||
| if (isInteger(strNumber) == InputType.INVALID) { | ||
| throw new IllegalStateException(ErrorMessage.INVALID_NUMBER.get()); | ||
| } | ||
| } |
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.
Error 클래스에 InputType이라는 클래스가 의존성이 생긴 것 같습니다.
에러와 입력을 담당하는 Input은 서로 의존성이 없어도 될 것 같다고 생각하는데, 어떻게 생각하시나요?
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.
생각해보니 Input 처리 목적으로 사용하려고 했던 클래스인데 이상한 곳에서 쓰고 있네요.
|
|
||
| import com.hyuunnn.lotto.Lotto; | ||
|
|
||
| public class BonusNumberError extends Error { |
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.
로또 자체를 검증하는 Error 클래스와 그를 상속받는 BonusNumberError로 사용하신 부분 좋은 것 같습니다!! 👍
|
|
||
| import com.hyuunnn.lotto.Util.InputType; | ||
|
|
||
| public class Error { |
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.
Error라는 네이밍 대신 Validator라는 네이밍은 어떠신가요?
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.
에러보다 유효한지 검증하는 것이 주 목적이라서 더 좋겠네요!
| } else if (matchCount == 6) { | ||
| return Rank.FIRST; | ||
| } | ||
| return null; |
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.
null을 반환할 수 있다면 Optional을 붙여주는 것도 좋을 것 같습니다!
| if (matchCount == 3) { | ||
| return Rank.FIFTH; | ||
| } else if (matchCount == 4) { | ||
| return Rank.FOURTH; | ||
| } else if (matchCount == 5) { | ||
| return checkBonusNumber(userLotto, bonusNumber); | ||
| } else if (matchCount == 6) { | ||
| return Rank.FIRST; | ||
| } |
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.
만약 "6등은 3개가 일치하고 bonusNumber가 일치하지 않아야 한다" 와 같은 요구사항이 추가되면 Rank와 WinningLotto 둘 다 수정해야 합니다.
만약 이 코드를 전혀 다른 사람이 수정한다고 치면, Rank 요구사항이 바뀌었는데, WinningLotto를 수정해야 한다고 생각하기 쉽지 않고, 놓칠 수도 있습니다.
이를 OCP 위반이라고 하는데, 시간이 되신다면 한 번 OCP를 지키는 코드를 만들어 보는 것도 좋을 것 같습니다!
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.
디자인 패턴도 공부해서 반영해보겠습니다 ㅎㅎ
isNumeric 메서드는 일반적으로 많이 사용하는 방법이기 때문에 boolean으로 return 받는 방법으로 수정
해당 클래스의 기능들은 입력이 유효(validate)한지 검증한다.
이전에는 순위 조건이 추가될 때마다 if문이 늘어났는데, 이를 해결하는 코드를 작성하였다.
Bonus.NONE은 보너스 볼에 매치가 되거나, 그 반대여도 true를 반환한다는 것을 명시하기 위함
| if (this == Bonus.NONE) { | ||
| return true; | ||
| } | ||
| return match == bonusMatch; |
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.
return this == Bonus.NONE ? true : match == bonusMatch;이런 부분은 삼항 연산자 쓰는게 더 깔끔해보이는데, 챌린지 규칙이 사용 금지라서 아쉽네요.
Match는 5일 때 중복되기 때문에, 중복될 수 없는 price를 key로 사용
winningNumberList, bonusNumber 변수는 winningLotto에 인자 값으로 1번 사용됩니다.
|
#1 (comment) 어떻게 처리하면 좋을지 괜찮은 아이디어가 떠오르지 않아서 이전에 사용했던 추가로 java hashmap 구현 코드에서 |
shkisme
left a comment
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 GameInput { | ||
|
|
||
| public int inputPrice() { | ||
| while (true) { |
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 ( ;; ) 형태로 표현하면 true에 의존하지 않아서 개인적으로 더 좋은 것 같네요... 저는 처음 본 패턴인데, 배워갑니다! 👍👍
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.
지인 찬스를 사용해봤는데, 대부분 while (true), while (1)을 그냥 사용한다고 하네요 ㅎㅎ..
제가 생각하기에는 init / condition / step이 존재하는 무한루프의 형태일 때 사용하는 것 같아요.
for (int binCount = 0; ; ++binCount) { ~~~ }
for (TreeNode<K, V> pointer_node = root; ; ) { ~~~ }java hashmap 구현 코드의 일부입니다.
| System.out.println("보너스 볼을 입력해 주세요."); | ||
| int bonusNumber = inputBonusNumber(winningNumberList); | ||
|
|
||
| winningLotto = new WinningLotto(new Lotto(winningNumberList), bonusNumber); |
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.
해결하셨군요 👍👍 계속 코드를 발전시키는 점 본받고 싶네요...ㅎㅎ
방치된 제 코드를 보니 반성하게 됩니다😓
| } | ||
| } | ||
|
|
||
| enum ErrorMessage { |
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.
Validator 도 각각 분리하고 ErrorMessage도 그에 맞게 nest로 둔 점... 진짜👍
gusah009
left a comment
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.
너무너무 고생 많으셨습니다!!
테스트 코드 하나하나에도 정성이 느껴집니다. 👍 👏
나중에 시간나시면 출력값을 검증하는 테스트코드도 제작해보면 좋을 것 같습니다! 👍 👏
| enum Bonus { | ||
| MATCH(true), | ||
| MISMATCH(false), | ||
| NONE(true); |
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.
Bonus enum 클래스를 활용해서 확장성있게 만드셨네요!! 좋습니다! 👍
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.
15979dd 에서 Rank 클래스의 isMatch와 Bonus 클래스의 isMatch를 만들어서 연결하니까 직관적이네요 ㅎㅎ
| public static boolean isNotInteger(String str) { | ||
| try { | ||
| strToInteger(str); | ||
| } catch (NumberFormatException e) { | ||
| return true; | ||
| } | ||
| return false; | ||
| } |
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.
혹시 Util의 isNotInteger와 Validator 클래스의 checkInteger의 차이를 알 수 있을까요?
사용성이 비슷한 것 같은데 서로 다른 두 메서드를 둔 이유가 궁금합니다!
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.
실수입니다 ㅠㅠ.. 처음에 개발할 때는 단순히 숫자인지 체크하는 기능이라서 Util 클래스에 넣었는데, 지금 보니 검증할 때를 제외하면 사용되지 않네요.
Validator 클래스로 옮기겠습니다..!
| } | ||
|
|
||
| lotto = new Lotto(testList); | ||
| assertThat(lotto.getLottoList().size()).isEqualTo(i); |
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.
위 코드를 아래와 같이 바꿔도 좋을 것 같습니다!
assertThat(lotto.getLottoList()).hasSize(i);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.
감사합니다 :)
| @Test | ||
| @DisplayName("WinningLotto match 메서드 테스트") | ||
| public void WinningLottoMatchTest() { | ||
| List<Integer> lottoList = Arrays.asList(1, 2, 3, 4, 5, 6); | ||
| assertRank(Arrays.asList(1, 2, 3, 4, 5, 6), lottoList, 7, Optional.of(Rank.FIRST)); | ||
| assertRank(Arrays.asList(1, 2, 3, 4, 5, 7), lottoList, 7, Optional.of(Rank.SECOND)); | ||
| assertRank(Arrays.asList(1, 2, 3, 4, 5, 8), lottoList, 7, Optional.of(Rank.THIRD)); | ||
| assertRank(Arrays.asList(1, 2, 3, 4, 8, 9), lottoList, 7, Optional.of(Rank.FOURTH)); | ||
| assertRank(Arrays.asList(1, 2, 3, 4, 8, 7), lottoList, 7, Optional.of(Rank.FOURTH)); | ||
| assertRank(Arrays.asList(1, 2, 3, 8, 9, 10), lottoList, 7, Optional.of(Rank.FIFTH)); | ||
| assertRank(Arrays.asList(1, 2, 3, 8, 9, 7), lottoList, 7, Optional.of(Rank.FIFTH)); | ||
| assertRank(Arrays.asList(1, 2, 8, 9, 10, 11), lottoList, 7,Optional.empty()); | ||
| assertRank(Arrays.asList(1, 8, 9, 10, 11, 12), lottoList, 7, Optional.empty()); | ||
| assertRank(Arrays.asList(8, 9, 10, 11, 12, 13), lottoList, 7, Optional.empty()); | ||
| } |
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.
우창님이 알려주신 방식인데, 이런 방법을 사용해봐도 좋을 것 같습니다!
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.
감사합니다! 참고해보겠습니다 ㅎㅎ
Validator에서 유일하게 사용되고 있으므로 가까운 위치로 옮겼다.
size()를 호출하여 비교하는 것이 아닌, assertThat에 구현되어 있는 hasSize를 사용
확실히 다른 챌린지와 다르게 요구사항이 많아서 생각할게 많네요.
밤새면서 했더니 눈에 잘 안들어오네요 ㅋㅋ..
정신 멀쩡할 때 다시 확인해보고 지속적으로 업데이트하겠습니다 ㅎㅎ..
이번 문제는 테스트 코드가 필요하다는 생각이 들었습니다 ㅎㅎ..
얼른 만들어서 올리겠습니다..