-
Notifications
You must be signed in to change notification settings - Fork 66
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
[LBP] 박세은 로또 미션 2-5단계 제출합니다. #87
base: seun0123
Are you sure you want to change the base?
Conversation
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~5단계 미션 고생하셨습니다 👍 👍
이번 요구사항을 잘 준수하셨네요! 😊
다만, 각 객체를 포장하는 과정에서 필드와 getter, setter만 존재하는 객체가 많아진 점이 조금 아쉽습니다.
객체가 단순한 데이터 보관소가 아니라, 자기 역할을 수행하도록 해보는 건 어떨까요?
예를 들어, lottoNumber.getNumber()로 값을 꺼내서
일치하는지 비교하고 있다면, 객체에게 직접 요청할 수도 있습니다.
Before (데이터를 꺼내서 직접 처리)
int matchCount = 0;
for (LottoNumber number : myLotto.getNumbers()) {
if (winningNumbers.contains(number.getNumber())) {
matchCount++;
}
}
After (객체가 스스로 판단)
int matchCount = myLotto.countMatchingNumbers(winningNumbers);
- 데이터를 꺼내서 직접 조작하는 절차적 코드가 줄어들고,
- 각 객체가 자기 역할을 수행하며 응집도가 높아집니다!
이 방향으로 리팩토링을 고려해보시면 좋을 것 같아요! 😄
질문 답변
LottoInputViewTest에서 입력 테스트를 진행할 때,
System.setIn(new ByteArrayInputStream(input.getBytes()))로 입력하면 NoSuchElementException이 발생했습니다.
이를 해결하기 위해@BeforeEach
에서 lottoInputView = new LottoInputView();를 초기화해도 동일한 문제가 발생하였고
결국, System.setIn()을 설정한 후 lottoInputView = new LottoInputView();를 다시 생성하는 방식으로 해결하였습니다.
해당 해결방법이 올바른 방향인지 궁금합니다!
이번 미션의 목표와 거리가 좀 있다고 생각해서 크게 중요하지 않은 것 같습니다.
System.in 테스트 코드 에러 해결 포스팅을 참고하면 그 이유를 더 잘 알 수 있을 것 같아요!
다시 돌아와서 입출력이 올바르게 나오는 것을 테스트하면 어떤 이점이 있을까요? 안전감, 변경 가능성 등을 모두 고려해보면 좋을 것 같아요! (+ 우선순위도)
ottoStatisticsService의 determineRank 메서드에서
WinningRank.valueOf(matchCount, bonusMatch)가 Optional을 반환하도록 구현했습니다.
매칭되는 등수가 없는 경우, Optional.empty()를 반환하여 flatMap(Optional::stream)을 사용해 안전하게 처리하도록 하였지만,
Optional을 사용하지 않고 예외를 던지는 방식(NullPointerException 등)으로 처리하는 방법도 고려해볼 수 있을 것 같습니다.
Optional.empty()를 반환하는 현재 방식과 예외를 던지는 방식 중 어떤 것이 현재 상황에 적절한 방식인지 궁금합니다!
지금 생각나는 간단한 방법으로는 당첨 금액이 없는
NO_PRIZE
같은 이넘을 만들고 관리할 수 있을 것 같아요.
(orElseGet()
을 사용하여 당첨되지 않았다면, 낙첨을 반환하는 형태)
이 기회에 Optional에 대해서도 학습해보면 좋을 것 같네요. 😄
참고 : Optional 관련
3번 질문
저는 테스트를 위한 코드를 실제 코드에 만드는 것은 선호하지 않습니다.
그러나 이미 있는 경우라면 활용할 수 있을 것 같아요. (private를 푸는 것이 아니라면.)
더 중요한 것은 그 메서드를 활용해서 테스트를 통과시키는 것이
정말 프로덕션 코드의 안전성을 보장하느냐?인 것 같아요.
더 고민해보시고 근거에 맞게 선택을 해보면 좋을 것 같아요.
마찬가지로 입출력 테스트보다, 도메인을 어떻게 객체지향적으로 다룰지에 대해 고민하는 것이 더 도움이 될 것 같아요.
public class LottoStatisticsService { | ||
private final Map<WinningRank, Integer> statistics; |
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.
앞서 답변드린 것과 같이, LottoStatisticsService의 책임을 고려하여
LottoStatistics와 LottoStatisticsService로 분리하여 리팩토링을 진행하였습니다.
이후 유지보수를 고려했을 때, ‘로또 통계’를 객체로 생성하여 관리하는 것이 더 적절할 것이라 생각되는데
물론, 객체로 관리할 경우 특정 시점의 통계를 저장하고 활용할 수 있는 장점이 있지만, 불필요한 상태를 가지게 될 수도 있는 단점도 분명히 존재하다고 생각됩니다,,
이 부분에 대해 어떻게 생각하시는지 궁금합니다!
말씀해주신 부분을 반영하여 리팩토링을 진행하면서, 클래스의 책임과 객체지향적인 코드에 대해 더욱 깊이 이해할 수 있었습니다. |
새로 사용한 개념
이번 미션과 유사한 풀이가 많이 검색되어 다른 블로거분들의 코드를 많이 활용하였습니다.
질문
LottoInputViewTest에서 입력 테스트를 진행할 때,
System.setIn(new ByteArrayInputStream(input.getBytes()))
로 입력하면 NoSuchElementException이 발생했습니다.이를 해결하기 위해 @beforeeach에서
lottoInputView = new LottoInputView();
를 초기화해도 동일한 문제가 발생하였고결국,
System.setIn()
을 설정한 후lottoInputView = new LottoInputView();
를 다시 생성하는 방식으로 해결하였습니다.해당 해결방법이 올바른 방향인지 궁금합니다!
LottoStatisticsService의 determineRank 메서드에서
WinningRank.valueOf(matchCount, bonusMatch)
가Optional<WinningRank>
을 반환하도록 구현했습니다.매칭되는 등수가 없는 경우,
Optional.empty()
를 반환하여flatMap(Optional::stream)
을 사용해 안전하게 처리하도록 하였지만,Optional을 사용하지 않고 예외를 던지는 방식(NullPointerException 등)으로 처리하는 방법도 고려해볼 수 있을 것 같습니다.
Optional.empty()
를 반환하는 현재 방식과 예외를 던지는 방식 중 어떤 것이 현재 상황에 적절한 방식인지 궁금합니다!LottoInputViewTest에서 작성된 입력 테스트 외에 남은 LottoInputView의 메서드의 테스트를 진행하기 위해서는
아래에 첨부한 LottoInputView의 메서드를 테스트 코드에서 활용해야한다는 생각이 드는데요.
테스트를 위해 private 메서드를 직접 추가하는 것이 적절한 방법일까요?
아니면, 테스트용 public 메서드를 생성하여 테스트 코드에서 활용하는 것이 더 적절할까요?
(현재 테스트 코드에서 활용하지 않았지만 임의로 해당 메서드를 public으로 변경한 상태입니다.)