Conversation
| view.winner(cars); | ||
| } | ||
|
|
||
| public static void nameException(String carName) { |
There was a problem hiding this comment.
메소드는 보통 동사로 작성하는 것이 관례입니다
해당 메소드는 자동차 이름이 유효한지 검증하는 메소드니까,
validCarName 이런 식으로 이름짓는 것이 적절해 보입니다
| @@ -0,0 +1,28 @@ | |||
| 자동차 경주 | |||
There was a problem hiding this comment.
감사합니다! 다음에는 클래스들의 역할과 구조를 추가해서 적어보겠습니다.
| 우승자 안내 문구 출력 기능 | ||
| - 우승자 안내, 쉼표로 우승자 나열 | ||
|
|
||
| `예외처리` |
There was a problem hiding this comment.
예외처리도 프로그램 설계할 때 정말 중요한 요소입니다
우선 작성해주신 코드를 봤을 때는 깔끔하게 예외처리 잘 해주신 것 같습니다!
추가로 다른 예외 상황(시도횟수에 소숫점을 입력했을 때, 시도횟수에 너무 큰 수를 입력했을 때 등)들도 있을지 더 고민해보시면 좋을 것 같습니다
There was a problem hiding this comment.
예외처리를 test파일에 있는 것만 생각했었는데 더 완벽한 프로그램을 위해서는 추가해야할 것 같습니다. 조언 감사합니다.
| int counts = tryCountNumCheckException(racingCount); // 예외처리 | ||
| tryCountException(counts); // 예외처리 | ||
|
|
||
| System.out.println(); |
There was a problem hiding this comment.
개행과 관련해서 팁을 드리자면,
println 보단 print('\n'); 으로 하는 것이 성능 상 이득을 볼 수 있습니다
그 이유도 함께 찾아보시면 좋을 것 같아요
src/main/java/racingcar/Racing.java
Outdated
|
|
||
| public void goOrStrop(Car car) { | ||
| int randomNum = Randoms.pickNumberInRange(0, 9); | ||
| if (randomNum >= 4) { |
There was a problem hiding this comment.
4와 같이 무언가 의미가 있는 숫자들은 상수로 처리하는 것을 권장합니다!
private static final int CAR_MOVE_STANDARD = 4;
public void goOrStop(Car car) {
int randomNum = randoms.picknumberInRange(0, 9(;
if (randomNum >= CAR_MOVE_STANDARD) ...
There was a problem hiding this comment.
조언 감사합니다. final로 초기화 이 후 재할당 할 수 없는 상수를 선언할 수 있는 것을 알게 되었습니다. 관례로는 언더바와 스네이크 표기법을 사용하는 것 또한 확인하였습니다. 변경하겠습니다!
|
레이싱 카의 코드를 객체지향적으로 리팩토링하였습니다. |
| throw new IllegalArgumentException("이름을 입력하지 않았습니다."); | ||
| } | ||
|
|
||
| if (carName.endsWith(",")) { |
There was a problem hiding this comment.
String에서 제공하는 메소드들을 잘 활용하고 계시네요! 좋습니다
| public static void eachNameException(String[] tokens) { | ||
| if (tokens.length == 0) { | ||
| throw new IllegalArgumentException("자동차를 적어야합니다."); | ||
| } | ||
| for (int i = 0; i < tokens.length; i++) { | ||
| if (tokens[i].length() > 5) { | ||
| throw new IllegalArgumentException("자동차 이름은 5자 이하만 가능합니다."); | ||
| } | ||
| if (tokens[i].isBlank()) { | ||
| throw new IllegalArgumentException("자동차 이름을 적어야 합니다."); | ||
| } |
There was a problem hiding this comment.
사소한 부분이지만,
if(token[i].length() > 5) 이랑 if(tokens[i].isBlank()) 부분의 위치를 서로 바꾸시는 것이 좀 더 효율적일 것 같습니다
자동차 이름이 빈칸이라면 자동차 이름 길이를 검증하는 것이 무의미하기 떄문입니다
추가로, 여기서 숫자 5도 마찬가지로 상수 처리해주시면 좋을 것 같습니다
| public static int tryCountNumCheckException(String racingCount) { | ||
| try { | ||
| int box = Integer.parseInt(racingCount); | ||
| return box; | ||
| } catch (NumberFormatException e) { | ||
| throw new IllegalArgumentException("시도 횟수는 숫자여야합니다."); | ||
| } |
There was a problem hiding this comment.
시도 횟수가 숫자인지를 체크하는 로직이 필요했었는데,
Integer.parseInt() 활용해서 잘 해주셨습니다!
| @@ -0,0 +1,23 @@ | |||
| package racingcar; | |||
|
|
|||
| public class Car { | |||
There was a problem hiding this comment.
작성해주셨던 위의 코드의 자동차 검증 관련(이름 길이, 빈칸 체크 등)을 여기 Car 객체 내의 private 메소드로 옮겨서 수행해주는 방법도 있습니다
또한 자동차 생성 시점에 이를 바로 확인시켜줄 수도 있습니다
public Car(String carName) {
this.carName = carName;
this.movement = 0;
validateCar();
}
private void validateCar() {
validateDuplicate();
validateBlank();
validateLength();
}
private void validateBlank() {
if (carName.isBlank()) {
throw new IllegalArgumentException("자동차 이름은 공백일 수 없습니다.");
}
}
...
| public String checkCarName() { | ||
| return carName; | ||
| } |
There was a problem hiding this comment.
아래 checkMovement() 과 마찬가지로,
보통 객체의 필드 값을 가져오는 메소드는 get___() 으로 이름 짓는 것이 관례입니다
intelliJ 내에서 Shift + Insert 키 누르시면 Getter와 Setter 메소드를 자동으로 넣어주는 기능도 있으니 사용해보시는 것을 추천드립니다!
public String getCarName() {
return carName();
}
src/main/java/racingcar/View.java
Outdated
| package racingcar; | ||
|
|
||
| public class View { | ||
|
|
There was a problem hiding this comment.
코드 작성하시면서 조사하셨겠지만,
지금 코드 작성해주신 구조는 MVC 구조에 해당합니다!
상단의 Car 클래스는 Model 에, Racing 클래스는 Controller, 그리고 여기 View 클래스는 View 요소에 해당됩니다
Spring 프레임워크에서도 이 방식을 사용하고 있기 때문에 자세히 공부해보시는 것이 좋을 것 같습니다
src/main/java/racingcar/View.java
Outdated
| for (int j = 0; j < cars.length; j++) { | ||
| if (cars[j].checkMovement() == max) { | ||
| if (sb.length() > 0) { | ||
| sb.append(", "); | ||
| } | ||
| sb.append(cars[j].checkCarName()); | ||
| } | ||
| } |
There was a problem hiding this comment.
이렇게 for문이 사용되는 부분들은 자바 스트림을 이용하시면 더 간결하게 코드를 작성해볼 수 있습니다
String result = Arrays.stream(cars)
.filter(car -> car.checkMovement() == max)
.map(Car::checkCarName)
.collect(Collectors.joining(", "));
|
|
||
| InputValidator.validCarName(carName); // 예외처리 | ||
|
|
||
| String[] tokens = carName.split(","); | ||
|
|
||
| Cars.validEqualName(tokens, uniqueElements); // 예외처리 | ||
|
|
There was a problem hiding this comment.
InputValidatr.validCarName() , Cars.validEqualName() 둘다 자동차와 관련된 검증인 것 같은데, 두 메소드를 서로 다른 클래스에 배치한 이유가 있을까요?
There was a problem hiding this comment.
Cars 클래스는 도메인 보다는 Car 에 대한 검증들이나 기능들을 모아둔 것 같은데, CarUtils, CarValidator 등으로 이름을 바꾼 다음 util 디렉토리로 옮기는 것이 더 좋아보입니다!
| public static void validCarName(String carName) { | ||
| if (carName == null || carName.isBlank()) { | ||
| throw new IllegalArgumentException("이름을 입력하지 않았습니다."); | ||
| } |
There was a problem hiding this comment.
이 부분은 상술했듯이 Car 객체 내부 메소드로 옮기거나, 아니면 CarValidator 클래스를 만든 다음 그곳으로 옮기는 것이 좀 더 옳은 방향인 것 같습니다
| public static void viewStartResult(String[] tokens, int counts, Car[] cars) { | ||
| System.out.print('\n'); | ||
| System.out.println("실행 결과"); | ||
| for (int i = 0; i < counts; i++) { |
There was a problem hiding this comment.
메소드 이름이 조금 모호한 것 같은데, 경기 상황을 출력하는 메소드이므로 viewRaceStatus 등으로 바꾸는 것이 좀더 적절해보여요! 이에 대한 지호님의 의견도 궁금합니다..!
test 코드가 정상 작동하지 않으나 일단 해결한 만큼이라도 제출합니다.
생각보다 예외처리나 신경써야할 것이 많았고, 커밋과 함수를 더 잘게 쪼개지 못한 것 같아 아쉽습니다.
객체지향적으로 문제를 해결하지 못한 게 아쉬운 거 같아 더 공부하고 고쳐야할 것 같습니다.