-
Notifications
You must be signed in to change notification settings - Fork 446
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
[1단계 - 자동차 경주 구현] 레디(최동근) 미션 제출합니다. #728
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.
안녕하세요 레디 👋
첫 번째 미션 구현 잘 해주셨습니다.
몇 가지 코멘트 남겼으니 다음 단계에 반영해주세요!
CarName carName = new CarName(name); | ||
Assertions.assertThat(carName.getName()).isEqualTo(name); | ||
} | ||
} |
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.
POSIX new line에 대해서 알아볼까요?
인텔리제이에서는 옵션으로 항상 개행을 붙여줄 수 있습니다 :)
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.
테스트 패키지 안에 클래스만 개행이 추가가 안되고 있었는데 올려주신 링크 덕분에 해결했습니다!
|
||
public class ExceptionRoofer { | ||
|
||
public static <T> T generate(final Supplier<T> supplier, final Consumer<String> consumer) { |
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.
제가 구현을 한다면 에러가 날 가능성이 있는 재귀를 사용하지는 않을 것 같네요.
depth를 1로 두면서 재입력을 받게 구현도 가능합니다. 이건 시간을 들여서 고민해보시면 좋을 것 같아요.
다만, 에러가 나면 그냥 에러가 나게 두는 것도 방법입니다. 특별한 요구사항이 없다면 재입력 없이 에러가 나게 둬도 좋을 것 같아요.
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.
재입력 받고 싶은 욕심이 있었네요😅
public class ExceptionRoofer { | ||
|
||
public static <T> T generate(final Supplier<T> supplier, final Consumer<String> consumer) { |
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.
람다를 파라미터로 받을 때의 가독성, 유지보수의 용이함 등을 고민해보시면 좋을 것 같습니다.
public record CarDto(String name, int position) { | ||
|
||
public static CarDto from(final Car car) { | ||
return new CarDto(car.getName(), car.getPosition()); |
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.
이 미션에서 DTO가 필요할까요? DTO의 어떤 특징/장점을 살리고 싶어서 사용하셨나요?
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.
DTO의 장점은 model과 view의 중간단계에서 model와 view가 서로 직접적으로 의존하지 않게 함으로써 변경에 쉽게 대응할 수 있다는 점이라고 생각합니다.
질문을 주신걸 보고 다시 코드를 살펴보니 현재 CarDto는 Car와 필드가 완전히 똑같기에 위의 장점을 살리지 못하고 있는거 같네요🤨
throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_NAME.get()); | ||
} | ||
|
||
if (name.trim().length() > MIN_LENGTH) { | ||
throw new IllegalArgumentException(ErrorMessage.INVALID_CAR_NAME.get()); |
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.
- 저도 이번 미션에서는 표준 예외를 사용했을 것 같습니다. 이번 미션에서는 커스텀 예외를 사용하는 장점을 느끼기 힘들 것 같아요.
- 예외 내용의 상세함은 정책에 따라 달라지는 사항입니다. 보안이 필요하다면 자세하게 알려주지 않는 게 더 나을 때도 있겠죠. 이 부분은 레디가 미션에 맞게 고민해보시면 좋을 것 같아요. 다만, 많은 경우에서 예외 내용이 상세했을 때 얻는 이득이 더 컸던 것 같네요.
|
||
import racingcar.message.ErrorMessage; | ||
|
||
public class CarName { |
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.
CarName이라는 명확한 이름이 생겼고, 자동차 이름은 5이하라는 제약조건을 자동차가 아닌 자동차 이름이 책임질 수 있어 응집도가 높아진다고 생각합니다!
import java.util.stream.Collectors; | ||
import racingcar.message.ErrorMessage; | ||
|
||
public class Cars { |
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.
비즈니스에 딱 맞는 자료구조를 만들 수 있습니다! 일급 컬렉션을 만들면 검증이나 요구사항을 외부에서 수행하는 것이 아니라 외부에서는 수행하라는 메시지만을 보내고 수행 로직은 일급 컬렉션이 스스로 결정할 수 있다는 장점이 있습니다.
public List<Car> findWinner() { | ||
final int maxPosition = getMaxPosition(); | ||
|
||
return cars.stream() | ||
.filter(car -> car.getPosition() == maxPosition) | ||
.toList(); | ||
} | ||
|
||
private int getMaxPosition() { | ||
return cars.stream() | ||
.mapToInt(Car::getPosition) | ||
.max() | ||
.orElseThrow(IllegalStateException::new); | ||
} |
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.
지금 로직도 훌륭하지만 조금 더 극단적으로 getter를 사용하지 않는 훈련을 해봐도 좋을 것 같아요.
Car 객체에 적당한 책임을 부여하는 방식을 사용하면 getter를 사용하지 않아도 될 것 같아보여요.
두 Car 중에 winner가 누군지 찾는 로직, 두 Car 객체가 비겼는지 판단하는 로직 등을 만들어보는 건 어떨까요?
return cars.stream() | ||
.mapToInt(Car::getPosition) | ||
.max() | ||
.orElseThrow(IllegalStateException::new); |
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.
예외에 메세지를 담아볼까요?
static class TestNumberGenerator implements NumberGenerator { | ||
|
||
private static int value = 2; | ||
@Override | ||
public int generate() { | ||
return value++; |
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.
꽤나 위험한 방식의 테스트인 것 같습니다.
테스트가 추가/제거될 때 TestNumberGenerator 때문에 다른 테스트가 깨질 수도 있을 것 같아요.
항상 움직이는 Generator와 항상 움직이지 않는 Geneartor를 만들어서 테스트에 사용하면 테스트도 명확해지고 테스트 간의 연관관계도 끊어낼 수 있을 것 같습니다.
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.
남겨주신 질문에 대한 답변 남깁니다!
CarName carName = new CarName(name); | ||
Assertions.assertThat(carName.getName()).isEqualTo(name); | ||
} | ||
} |
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.
테스트 패키지 안에 클래스만 개행이 추가가 안되고 있었는데 올려주신 링크 덕분에 해결했습니다!
public Car copy() { | ||
return new Car(name, position); | ||
} |
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.
좋은 의견 감사합니다!!
public record CarDto(String name, int position) { | ||
|
||
public static CarDto from(final Car car) { | ||
return new CarDto(car.getName(), car.getPosition()); |
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.
DTO의 장점은 model과 view의 중간단계에서 model와 view가 서로 직접적으로 의존하지 않게 함으로써 변경에 쉽게 대응할 수 있다는 점이라고 생각합니다.
질문을 주신걸 보고 다시 코드를 살펴보니 현재 CarDto는 Car와 필드가 완전히 똑같기에 위의 장점을 살리지 못하고 있는거 같네요🤨
|
||
public class ExceptionRoofer { | ||
|
||
public static <T> T generate(final Supplier<T> supplier, final Consumer<String> consumer) { |
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.
재입력 받고 싶은 욕심이 있었네요😅
|
||
import racingcar.message.ErrorMessage; | ||
|
||
public class CarName { |
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.
CarName이라는 명확한 이름이 생겼고, 자동차 이름은 5이하라는 제약조건을 자동차가 아닌 자동차 이름이 책임질 수 있어 응집도가 높아진다고 생각합니다!
import java.util.stream.Collectors; | ||
import racingcar.message.ErrorMessage; | ||
|
||
public class Cars { |
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.
비즈니스에 딱 맞는 자료구조를 만들 수 있습니다! 일급 컬렉션을 만들면 검증이나 요구사항을 외부에서 수행하는 것이 아니라 외부에서는 수행하라는 메시지만을 보내고 수행 로직은 일급 컬렉션이 스스로 결정할 수 있다는 장점이 있습니다.
안녕하세요 범블비!
레디라고 합니다:)
리뷰 받았으면 좋을 것 같은 부분 남겨보아요!
예외 커스텀
예외 입력시 재입력 받는 기능을 구현하는 코드
한 메서드에 오직 한 단계의 들여쓰기(indent)만 한다.
가 있어 이 조건을 맞추기 위해 결국 재귀를 사용하여 구현을 하였습니다.final과 관련된 질문