피드백) 1-1(자동차경주) 코드리뷰
레벨1 1단계 자동차 경주 피드백 1,2차 모음
📜 제목으로 보기
자경 미션 피드백
네이밍
- if절에 들어가는 메서드명은
is~
,has~
로 시작하자. - VO의 새객체 반환 메서드네이밍을
toNextRound()
로 잡았다. to는 괜찮을까?- toString, toDto 같이 형 변환시에만 사용하자.. 또 바꿔야겟넹..
getNextRound()
- toString, toDto 같이 형 변환시에만 사용하자.. 또 바꿔야겟넹..
-
Util이라는 추상적인 이름 대신
Validator
처럼 구체적인 이름으로 클래스 잡기 -
조건문 전체가 아니라,
일부 값
비교에서도네이밍을 변수로 추출
하는게 좋다private static void checkDuplicated(List<String> carNames) { if (carNames.stream().distinct().count() != carNames.size()) { long distinctCountOfCarNames = carNames.stream().distinct().count(); if (distinctCountOfCarNames != carNames.size()) {
- 추출할 때, 메서드의 인자는
구체적으로X 좀더 추상적으로
정의해주기
체크
- 메소드 사용 순서대로 배치후 commit ->
커밋전 체크리스트화
- structure(alt+7)
- 불필요 공백 제거후 coimmit
- 테스트 코드 돌리고 commit
- @parameterizedTest <-> @Test
- intellij 상수, 변수추출을 private으로 최초 1번 옮겨주기
-
유틸이라도 해당 class에서만 사용된다면,
private
으로 변경해줘야한다. static 유틸 클래스는 private생성자로 객체생성없음을 명시해주기
-
상수 <-> 멤버변수 개행 1줄
넣어주기 - 전략메서드에는 인페/클래스명에 있는 목적어(number)를 repeat할 필요없다. 동사(generate)만
검증
-
실수로 기입된
내부공백(Blank)
검사는문자열숫자의 format
검사가 있다면 안해도 된다. -
부정조건문 없애자
생성자
-
static 유틸 클래스는 private생성자로 객체생성없음을 명시해주기
-
접근제한자 기본은 private으로 바꿔주기
-
도메인은 input이외에 자체 검증 ->
input에서는 공통검증 / 도메인 자체검증 생성자
- 생성자 로직
- private 기본 생성자
- public from( 원본
List< Car>
) + Cars검증로직(중복 등) - public fromNames or fromInput(
List< String >
) + Cars검증로직(중복 등)
- 테스트에서 단일-> 단일List 만든 뒤,
- 단일 조정 by메서드 -> 단일List에 반영 -> 반영된 단일List로 일급컬렉션 생성
- 불변을 위해 포인터의 포인터 사용을 막아야하는데,
테스트에서는 포포를 사용할 수 있게 inputString List가 아닌 단일객체List로부터 만드는 생성자(정펙매) 추가
기본
-
split은 2번재 인자를 줘야,
,,
를 안씹고 간다. ->split( , -1)
String[] split = ",,".split(","); // count 0 String[] split1 = ",,a".split(","); // 3 String[] split2 = ",a,".split(","); // 2 String[] split3 = "a,,".split(","); // 1
-
split후 trim까지 해서 반환해야
a, a
를 다른 것으로 인식한다. ->split(,-1).map(String::trim)
return Arrays.stream(value.split(delimiter, -1)) .map(String::trim) .collect(Collectors.toList());
-
convert나 split관련 기본api가 충분하면, 유틸 메서드로 따로 빼지말고 그냥 사용하자. 지식만 늘어난다.
-
조건문의 전략객체(Functional interface)에는
() ->
람다식으로 테스트한다.
VO, DTO
-
Dto는 controller에 일단 넣어준다.
- ROUND는 hasNext패턴으로 줄어가는데,
생성자 검증은 1이상
<->1씩 줄여가니 0까지는 감.
- 생성자에서 검증하되, 새객체 반환은
검증없는 private 기본생성자
이용
- 생성자에서 검증하되, 새객체 반환은
-
DTO는 VO나, 포장객체 없이 only 원시값들로 필드가 구성 ->
Dto사용을 위한 원본 getter에서는 VO->value까지 최종반환시킨 getter
-
VO를 가진 단일객체의 compareTo에 원시값 비교 x ->
VO로 비교
->VO도 비교가능
하게 -
정펙매 생성자 중간에 VO가 등장할 경우, getter()를 써도 된다.
-
VO는 검증/불변을 위해 래핑한 것이므로, 도입했다고 굳이 정펙매를 외부에 오픈안해도 된다
private Cars getCars() { try { return Cars.fromNames(InputView.getCarNames()); //Cars.fromNames(Names.fromInput(InputView.getCarNames()));
- 같은 context에서 사용될 일이 없는, 객체 생성 가운데 활용되는 객체들은 구현을 드러내지 않는 것이 좋을 것 같습니다!
테스트
-
DTO의 테스트는 view처럼 자주 바뀌는 DTO에 대해 테스트를 생각해본다.
-
DisplayName은 너무하다 싶을정도로 자세히 쓴다.
class NameTest { //@DisplayName("이름이 1자 미만, 5자 초과일 경우") //@DisplayName("자동차 이름이 1자 미만, 5자 초과하여 유효하지 않은 경우") @DisplayName("자동차 이름이 1자 미만, 5자 초과하여 유효하지 않은 경우 예외가 발생한다")
- 이정도로 결과까지 명확하게 서술하면 더 좋습니다.
-
@ValueSource
의 빈 문자열과@EmptySource
가 같은 값을 제공하지 않나요?@EmptySource @ValueSource(strings = {"", "Wishoon", "123456"})