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

[2단계 - 로또 구현] 다니(이다은) 미션 제출합니다. #322

Merged
merged 21 commits into from
Feb 27, 2021

Conversation

da-nyee
Copy link

@da-nyee da-nyee commented Feb 25, 2021

안녕하세요, 코니! 다니입니다 🤗
이번 단계도 코드 리뷰 잘 부탁드립니다!

이번 미션을 진행하면서 크게 변화가 있었던 내용들을 먼저 작성하겠습니다!

변경한 내용 1.

2단계를 시작하기 앞서 1단계 피드백과 코드를 살펴봤는데, 몇 개의 로또를 구매했는지 출력하는 기능을 깜빡했더라구요ㅠ 데드라인을 맞춰야겠다는 생각에 급하게 만들어서 이런 실수를 한 것 같습니다...! 그래서 이 부분 먼저 완성시키고 진행했습니다!

변경한 내용 2.

1단계에서는 로또 상금 테스트를 1등, 2등, 상금이 없는 경우만 했습니다. 그런데, 이번에 나머지 케이스도 테스트 해보니까 3등 결과가 2등 결과로 반환되는 버그가 있었습니다. if 문의 조건식을 수정하고 stream에 findAny() 대신 findFirst()로 변경해서 해결했습니다! 이 일로 꼼꼼한 테스트가 정말 중요하다는 걸 느끼게 되었습니다.

변경한 내용 3.

2단계의 요구사항인 로또 수동 구매 기능을 추가 구현했습니다. 수동, 자동 구매 개수 원시값을 포장하기 위해 Quantity 객체를 생성했습니다. 코드를 작성하면서 이렇게 하는 게 맞는 건가..? 싶은 부분이 꽤 있었는데요. 제가 궁금했던 점은 바로 아래에 정리해서 질문 드리겠습니다!

이어서 궁금했던 점들을 작성하겠습니다!

궁금한 점 1.

로또 수동 구매에서 수동으로 구매할 번호를 입력하는 기능을 구현할 때, View가 Domain에 의존하면 안 되니까 LottoTicket으로 먼저 포장하지 못하고 List 내에 List<Integer>로 각 입력을 저장해서 반환하게 작성했는데요. 이렇게 List<List<Integer>> 두 번 중첩해서 사용하는 게 괜찮은 방법인가요...?! 가독성이 떨어지는 거 같아 고민되는데.. 혹시 더 좋은 방법이 있을까요??

궁금한 점 2.

Controller에서 createLottoTickets 메소드를 createManualLottoTickets, createAutoLottoTickets 두 메소드로 분리해서 작성했습니다. 그런데, 각 메소드의 라인 수가 길지 않아 굳이 분리할 필요가 있었을까? 라는 의문이 생겼습니다. 만약 메소드를 분리하지 않고 함께 작성하면 createLottoTickets가 수동 로또 만들기, 자동 로또 만들기 2개의 책임을 가진 것 같아 우선은 분리했는데요. 근데 이름만 보고 생각하면 로또 만들기라는 1개의 책임만 가진 거 같기도 하구요....! 지금처럼 분리한 상태로 두는 게 좋을까요, 아니면 하나로 합치는 게 더 나을까요?? 리뷰어님의 의견이 궁금합니다!!

코드를 작성하면서 부족한 점이 너무 많은 것 같아 얼른 리뷰를 받고 싶었습니다!
이번에도 리팩토링이 필요하다 느껴지는 부분이 있다면 부담 없이 전부 지적해주세요!

바쁘신 와중에 귀한 시간 내주셔서 감사합니다 ❣

- 구현할 기능 목록 수정
- 확인할 프로그래밍 목록 수정
- 구현할 기능 목록 수정
- 확인할 프로그래밍 목록 수정
- 3등 결과도 2등 결과로 반환되는 버그 수정
- 수동으로 구매할 로또 수가 음수인 경우 예외를 발생시키는 기능 구현
- 구입금액으로 살 수 있는 최대 개수를 초과한 경우 예외 발생
- 숫자가 아닌 경우 예외 발생
- 공백인 경우 예외 발생
- 숫자가 아닌 경우 예외 발생
- 공백인 경우 예외 발생
- 1~45의 범위가 아닌 경우 예외 발생
- 6개보다 적거나 많은 숫자를 입력한 경우 예외 발생
- 중복되는 숫자를 입력한 경우 예외 발생
@da-nyee
Copy link
Author

da-nyee commented Feb 25, 2021

📚 다니의 학습 로그

[Java] 문자열 - 5

내용

  • 제이슨의 강의를 듣고 학습한 내용을 블로그에 정리함
  • 문자열 객체를 new로 생성하는 것과 ""로 생성하는 것의 차이를 알게 됨
  • String Pool, StringBuilder 등 새로운 개념들을 알게 됨

링크

[Java] stream findAny(), findFirst() 차이 - 3

내용

  • Rank 객체에서 등수에 대한 정보를 반환하기 위해 stream API를 활용함
  • 원래는 findAny()를 썼는데, 테스트 도중 이 메소드가 매번 같은 값(ex. 첫번째 값) 반환을 보장하지 못한다는 사실을 알게 됨
  • 반면, findFirst()는 항상 첫번째 값 반환을 보장하기 때문에 이 메소드를 사용하도록 변경함

링크

[Java] HashMap vs EnumMap - 3

내용

  • 얼마 전에 크루 한 명이 EnumMap의 존재와 이 구현체가 HashMap보다 성능이 좋다는 사실을 알려줌
  • 두 구현체의 특징을 찾아보고 기존에 HashMap으로 작성했던 코드를 EnumMap으로 변경함
  • EnumMap은 Key 값으로 무조건 enum 클래스를 가져야 한다는 조건을 알게 됨

링크

Copy link

@choihz choihz left a comment

Choose a reason for hiding this comment

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

안녕하세요 다니!

2단계를 아주 깔끔하게 잘 구현해 주셨네요. 부족한 점이 많은 것 같다고 하셨는데, 자신감을 가지셔도 돼요! 👏

남겨주신 코멘트를 보고 앞으로는 더 꼼꼼히 리뷰해야겠다는 반성을 하게 되었어요.. 3등이 2등이라니... 😞 그래서 열심히 보았는데 특별히 코멘트를 남길 부분이 없어 보여요~ 2단계 구현보다는 1단계에서 그때는 왜 안 보였지 싶은 사소한 개선사항이 몇 개 있긴 한데 넘어가도 될 것 같습니다 ㅎㅎ 혹시 공부할 만한 게 더 필요하시다면(?) JUnit 5를 이용해 다양한 테스트 케이스로 테스트해봐도 좋을 것 같아요. (참고)

그럼 로또 미션은 여기서 마무리하도록 할게요! 그동안 정말 고생 많으셨고, 다음에 또 만나요~

private static final String MESSAGE_STATISTICS = "당첨 통계\n--------\n";
private static final String STATISTICS_FORMAT = "%d개 일치 (%d원)- %d개";
private static final String STATISTICS_BONUS_FORMAT = "%d개 일치, 보너스 볼 일치(%d원) - %d개";
private static final String MESSAGE_LOTTO_TICKET_COUNT_FORMAT = "수동으로 %d장, 자동으로 %d개를 구매했습니다.";
Copy link

Choose a reason for hiding this comment

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

or ?

@@ -4,11 +4,17 @@
import java.util.List;

public class LottoMachine {
Copy link

Choose a reason for hiding this comment

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

생성자를 private으로 닫아주면 불필요한 객체 생성을 막을 수 있겠네요~


public class Statistics {
private static final Integer INITIAL_COUNT = 0;

private final Map<Rank, Integer> lottoStatistics = new HashMap<>();
private final Map<Rank, Integer> lottoStatistics = new EnumMap<>(Rank.class);
Copy link

Choose a reason for hiding this comment

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

👍

Comment on lines +53 to +60
private List<LottoTicket> createManualLottoTickets(long manualCount) {
List<List<Integer>> manualNumbers = inputView.scanManualNumbers(manualCount);
return LottoMachine.buyManual(manualNumbers);
}

private List<LottoTicket> createAutoLottoTickets(long autoCount) {
return LottoMachine.buyAuto(autoCount);
}
Copy link

Choose a reason for hiding this comment

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

메서드로 잘 분리되었다고 생각해요 👍

System.out.println(MESSAGE_WINNING_NUMBER);
return deleteWhiteSpaces(scanner.nextLine());
public List<List<Integer>> scanManualNumbers(long manualCount) {
System.out.println(MESSAGE_MANUAL_NUMBERS);
Copy link

Choose a reason for hiding this comment

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

수동 로또 개수가 0이어도 이 메시지가 노출되고 있네요~

return deleteWhiteSpaces(scanner.nextLine());
public List<List<Integer>> scanManualNumbers(long manualCount) {
System.out.println(MESSAGE_MANUAL_NUMBERS);
List<List<Integer>> manualNumbers = new ArrayList<>();
Copy link

Choose a reason for hiding this comment

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

여기선 List<List<Integer>>도 나쁘지 않다고 생각해요 👍 (너무 예스맨 같지만 ㅎㅎ)

@choihz choihz merged commit 5797367 into woowacourse:da-nyee Feb 27, 2021
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.

None yet

2 participants