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

[서브웨이] 3주차 -로또 코드리뷰 요청입니다. #146

Merged
merged 37 commits into from
Feb 24, 2020

Conversation

joseph415
Copy link

No description provided.

Copy link

@dave915 dave915 left a comment

Choose a reason for hiding this comment

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

서브웨이 안녕하세요! 리뷰를 맡게된 데이브 입니다.
구현 잘 하셨네요 😀
몇가지 피드백 남겼으니 확인 후 반영 부탁드릴게요!
추가로 궁금한 부분이 있다면 편하게 DM주세요!

Comment on lines +17 to +22
@CsvSource(value = {"1,2,3,4,5,6:FIRST_RANK",
"1,2,3,4,5,7:SECOND_RANK",
"1,2,3,4,5,10:THIRD_RANK",
"1,2,3,4,44,45:FOURTH_RANK",
"1,2,3,43,44,45:FIFTH_RANK",
"1,2,40,41,42,43:NO_RANK"}, delimiter = ':')
Copy link

Choose a reason for hiding this comment

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

2번째와 4번째 테스트가 실패하네요 😭

Copy link
Author

@joseph415 joseph415 Feb 22, 2020

Choose a reason for hiding this comment

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

리팩토링하면서 enum상수값을 잘못 바꿔주었네요,, 테스트를 돌려본줄 알았는데 죄송합니다 ㅠ
다음에는 다시한번확인하겠습니다.!

WinningBalls winningBalls = new WinningBalls(winningBallValues, bonus);
int correctCount = winningBalls.hitLottoBalls(new LottoTicket(lottoTicket));
boolean correctBonusNumber = winningBalls.hitBonusBall(new LottoTicket(lottoTicket));
Assertions.assertThat(winningRank).isEqualTo(WinningRank.determineRank(correctCount, correctBonusNumber));
Copy link

Choose a reason for hiding this comment

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

예상값을 뒤에 넣어주셔야 Junit테스트 실패시
Expected가 winningRank값
Actual이 WinningRank.determineRank(correctCount, correctBonusNumber) 값이 나옵니다 :)

Assertions.assertThat(WinningRank.determineRank(correctCount, correctBonusNumber)).isEqualTo(winningRank);

Copy link
Author

Choose a reason for hiding this comment

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

아 사소한것에 실수가 있었네요 assertj 다시 한번 공부하겠습니다 :)


public static WinningRank determineRank(int correctNumber, boolean isBonusNumber) {
return Arrays.stream(values())
.filter(result -> result.winningBallCount == correctNumber && result.isBonusBall == isBonusNumber)
Copy link

Choose a reason for hiding this comment

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

filter 내부가 명시적으로 보기 힘들어요 😭
메소드 분리해 어떤 판별을 하는건지 명시적으로 보이게 하면 좋을 것 같아요.

import java.util.List;

public class WinningBalls {
private final List<LottoBall> winningBalls;
Copy link

Choose a reason for hiding this comment

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

LottoTicket과 winningBalls의 다른점은 무엇일까요? 🤔

Copy link
Author

@joseph415 joseph415 Feb 22, 2020

Choose a reason for hiding this comment

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

LottoTicket은 티켓을 만들어 주는 역할을 위해 만들었고
WinningBalls는 지난주 당첨번호티켓를 담기위해 만든 클래스였습니다..혹시 두 클래스를 합처야 하나요?
우선은 의미를 명확하게 하기 위해 WinningTicket 이라고 클래스명을 바꾸겠습니다!

Copy link
Author

@joseph415 joseph415 Feb 22, 2020

Choose a reason for hiding this comment

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

혹시 일급컬랙션에 인스턴스 변수가 final로 선언이 안되었던것이 다른점이였나요? 수정했습니다!
-> 본질적으로 같다는 의미


private void validateWinningBallsWithDuplicatedBonusBall() {
if (winningBalls.contains(this.BonusBall)) {
throw new DuplicationException("보너스 볼이 중복입니다. 당첨 번호를 다시 입력해주세요.");
Copy link

Choose a reason for hiding this comment

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

CustomException으로 추가적으로 해주는일이 없다면 표준 예외를 사용하는 것이 어떨까요?

아래 글 중 Item 72. 표준 예외를 사용하라를 읽어보세요!
https://badcandy.github.io/2019/01/01/effective-java-3rd-chapter10/

try {
return Integer.parseInt(inputValue);
} catch (NumberFormatException e) {
throw new NumberFormatException("숫자가 아닙니다. 재입력 해주세요.");
Copy link

Choose a reason for hiding this comment

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

에러메세지도 상수로 올리면 어떨까요?

private List<LottoBall> winningBalls;

public WinningBallsUtils(String input) {
String[] winningBalls = input.split(",");
Copy link

Choose a reason for hiding this comment

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

하드코딩은 피해주세요! ","
그리고 관련된 코드별로 공백을주면 가독성이 더 좋아집니다 :)

    public WinningBallsUtils(String input) {
        String[] winningBalls = input.split(",");
        
        validateWinningBallsNumber(winningBalls);
        validateWinningBallsLength(winningBalls);
        validateDuplicatedWinningBalls(winningBalls);
        
        this.winningBalls = Arrays.stream(winningBalls)
                .map(Integer::parseInt)
                .map(LottoBallFactory::findByLottoBall)
                .collect(Collectors.toList());
        Collections.sort(this.winningBalls);
    }

}

private void validateDuplicatedWinningBalls(String[] winningBalls) {
Set<String> DuplicatedValidation = new HashSet<>(Arrays.asList(winningBalls));
Copy link

Choose a reason for hiding this comment

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

변수명의 첫글자는 소문자로 해주세요 :)

import java.util.*;
import java.util.stream.Collectors;

public class WinningBallsUtils {
Copy link

Choose a reason for hiding this comment

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

이 클래스는 유틸이라기 보단 winningBalls의 도메인 로직이라고 보이네요 🤔

Copy link
Author

Choose a reason for hiding this comment

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

도메인로직이 있는 부분을 따로 WinningTicket으로 분리하였습니다.

}

public int countRankPeople(List<WinningRank> winningRanks, WinningRank winningRank) {
return (int) winningRanks.stream().filter(Rank -> winningRank == Rank).count();
Copy link

Choose a reason for hiding this comment

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

람다식에서 파라미터 부분은 변수이기 때문에 앞글자를 소문자로 해주세요.
filter(rank -> winningRank == rank)

Copy link
Author

Choose a reason for hiding this comment

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

이전 미션부터 사소한 것에서 실수가 많이 나오네요,, 이런 실수를 줄이는게 가장중요한것 같네요ㅠㅠ 꼭 다음 번에는 꼼꼼히 확인하겠습니다!!😀

WinningRank 테스트의 예상값과 실제값의 인자 위치를 변경
WinningRank의 determineRank 메소드의 filter 내부를 명시적으로 표현하기위해 메소드로 분리
LottoTicket과 WinningBalls 클래스의 의미를 명확하게 하기 위해 WinningTicket 이라고 클래스명을 변경
DuplicationException을 표준예외로 변경
매직넘버 상수화 리팩토링후 테스트 확인
String Format으로 사용
WinningBallUtils 가 인스턴스 변수를 갖고 비지니스 로직을 갖는 부분이 있어서 WinningTicketFactory 클래스를 만들어 검증유틸 부분과 비지니스 로직을 나눴고 테스트를 추가
에러메시지 상수화
전체적인 리팩토링
custom exception을 모두 표준예외로 변경
LottoBallFactory에서 인스턴스 참조값을 주었던 메소드가 외부에서 변경가능성이 있어서 필요한 부분만 unmidifiableList를 통해 리턴해주도록 변경
LottoTicket과 WinningBallFactory의 본질적 기능이 같아 합침
Copy link

@dave915 dave915 left a comment

Choose a reason for hiding this comment

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

피드백 반영 한 부분 확인 했어요 💯
다음 Step 진행을 위해 여기서 머지 할게요!
혹시나 궁금한 점이 있으시면 언제든지 질문주세요!

@dave915 dave915 merged commit 03eeeae into woowacourse:joseph415 Feb 24, 2020
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