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

[자동차 경주] 조현석 미션 제출합니다. #89

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

jerry8282
Copy link

✅구현할 기능 목록

입력

  • Console.readLine() 메소드를 통해 입력
  • 레이싱할 자동차 이름 입력
  • 시도할 횟수 입력

자동차 이동

  • camp.nextstep.edu.missionutils.Randoms을 사용 (0~9사이 랜덤값 생성)
  • 랜덤값이 4 이상일 경우 자동차 전진

차수별 실행 출력

  • 각 시도 마다 "-"로 얼마나 전진 하였는지 표현

우승자 선정

  • 게임이 종료된 후, 가장 많이 전진한 자동차를 우승자로 선정
  • 최대 이동거리가 동일한 경우 공동 우승자로 선정

🚀리팩토링

  • mvc패턴을 적용하여 가독성과 유지보수를 높임
  • 함수를 최대한 한가지 일만 하도록 만들어 depth를 줄임

🎯예외 처리

  • 자동차 이름이 5자가 넘을 경우 예외처리
  • 시도 횟수가 1보다 작을 때 예외처리
  • 시도 횟수와 자동차 입력값이 Null일 때 예외처리
  • 자동차 이름이 중복일 때 예외처리 -> 자동차 이름이 중복일 때 중복인 부분만 제거

Copy link

@wjdrjs00 wjdrjs00 left a comment

Choose a reason for hiding this comment

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

2주차 수고하셨습니다!! 부족한 실력이지만 조심스럽게 몇가지 리뷰 남겨봅니다!

Choose a reason for hiding this comment

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

mvc구조의 controller를 의도하고 사용하신거라면, 조심스럽지만 제 생각에는 RacingCarController은 컨트롤러 역할 이외의 역할도 담당하고 있어 보입니다!! 이번 기회에 controller는 어떤 역할을 담당하는지 model, view는 어떤역할을 담당하는지 알아보시면 좀더 명확한 책임을 가지며 구현할 수 있지 않을까? 생각해봅니다!🤔

Copy link
Author

Choose a reason for hiding this comment

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

정말 감사합니다!! mvc패턴을 조금 더 공부해서 다음 주차부터 개선해야겠네요!!

Comment on lines +12 to +16
private val inputView = InputView
private val errorView = ErrorView
private val outputView = OutputView
private val validateCarNames = ValidateCarNames
private val validateAttempts = ValidateAttempts

Choose a reason for hiding this comment

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

파일을 보니 object로 정의하셨는데, 변수에 다시 선언하면 object를 사용할 이유가 있을까요? 이미 object로 정의된 클래스는 싱글톤 형태로 존재해서 직접 접근하여 사용할 수 있습니다.
조심스럽게 class 키워드와 object 키워드의 차이를 알아보는걸 추천해봅니다!

Copy link
Author

Choose a reason for hiding this comment

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

object 키워드는 클래스를 정의함과 동시에 객체를 생성이였군요.. 많이 알아갑니다 감사해요!!

Comment on lines +4 to +6
fun errorMessage(message: String) {
println(message)
}

Choose a reason for hiding this comment

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

이렇게 단일표현식을 활용하시면 보다 간결하게도 표현할 수 있습니다.

Suggested change
fun errorMessage(message: String) {
println(message)
}
fun errorMessage(message: String) = println(message)

Copy link
Author

Choose a reason for hiding this comment

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

코드를 조금 더 간결하게 만들 수 있겠군요~!! 알려주셔서 감사해요

object InputView {
fun askForCarNames(): String {
println("경주할 자동차 이름을 입력하세요.(이름은 쉼표(,) 기준으로 구분)")
return Console.readLine()

Choose a reason for hiding this comment

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

개인적으로 전 이렇게 변수 선언을 한번 거친 후 리턴하는 방법을 통하면 좀 더 명확해지는거 같습니다!!😃

Suggested change
return Console.readLine()
val carNames = Console.readLine()
return carNames

return if (carNames.size != carNames.toSet().size) {
outputView.displayDup()
carNames.toSet()
} else carNames

Choose a reason for hiding this comment

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

코틀린 코딩 컨벤션에 if나 else 중 하나라도 중괄호를 사용했다면 다른 조건에도 중괄호를 넣는 걸 권장한다네요


object RandomUtils {
fun canMove(): Boolean {
return Randoms.pickNumberInRange(0, 9) >= 4

Choose a reason for hiding this comment

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

이런식으로 랜덤 함수에 바로 조건을 달아서 반환해줄 수 있는지는 몰랐네요
하나 배워갑니다!

Copy link

@UiHyeon-Kim UiHyeon-Kim left a comment

Choose a reason for hiding this comment

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

리뷰 남겨주셔서 감사합니다! 2주차도 고생하셨어요

Copy link

@DongchannN DongchannN left a comment

Choose a reason for hiding this comment

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

2주차 과제 고생 많으셨습니다!

validateCarNames.checkIfEmpty(carNames)
validateCarNames.checkLength(carNames)

return validateCarNames.checkDuplicates(carNames)

Choose a reason for hiding this comment

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

유효성 검사를 실시 할 때 Controller에서 어느 유효성 검사를 하는지 알 필요가 없다고 생각합니다.
validateCarNames.checkNames()만 호출하고, 그 안에서 Empty인지, Length가 유효한지 검사하면 깔끔할 것 같습니다


object ValidateCarNames {

private val outputView = OutputView

Choose a reason for hiding this comment

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

Validation과 View가 연결되어 있는 것보다 분리되는 것이 더 좋아보입니다.

@@ -0,0 +1,14 @@
package racingcar.utils

object ValidateAttempts {

Choose a reason for hiding this comment

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

위에서 보면 생성자를 호출해서 사용하시는데 상태가 없는 클래스의 경우 static 메서드로 객체 생성 없이 메서드를 호출하는 방법도 좋아보입니다!

import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.Assertions.assertEquals

class RacingCarControllerTest : NsTest() {

Choose a reason for hiding this comment

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

다음 과제부터는 하나의 파일에서 테스트를 하는 것보다 각 파일에 맞게 테스트를 작성하는 것도 추천드려요!

}
}

private fun findWinners(): List<String> {

Choose a reason for hiding this comment

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

Car model 뿐만 아니라, Racing과 같이 전체적인 자동차 경주를 담당하는 model을 만드는 것도 추천드립니다.
자동차 경주 담당 모델을 만들면, findWinners(), moveCars() 등과 같은 메서드들을 분리할 수 있을 거에요!

Choose a reason for hiding this comment

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

제가 MVC 패턴을 잘 몰라서 그러는데, findWinners나 moveCars는 동작이라서 model에서 다룰 수 없지 않나요?
제가 알기로 model은 순수하게 데이터베이스로만 사용하는걸로 알고있어서 여쭤봅니다.
Controller에서의 분리를 말씀하시는 건가요?

Choose a reason for hiding this comment

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

MVC 패턴에서 Controller는 View와 Model을 연결해주는 역할을 하고, 주요 비즈니스 로직은 Model에 위치하는 것으로 알고있어요.
사용자의 입력이 Controller로 오면 Controller는 Model에 전달해주고, 다시 결과를 받아서 View에 전달해줍니다.

아마 개발하실 때 데이터베이스와 직접적인 관련이 있는 Domain이나 Entity와 약간 헷갈리신거같아요 👍

Choose a reason for hiding this comment

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

아하 아직 mvc 공부가 부족하네요 ㅠㅠ 자세히 알려주셔서 감사합니다!

Copy link

@Grove1212 Grove1212 left a comment

Choose a reason for hiding this comment

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

MVC 패턴을 적용하시고 기능에 맞는 파일 분리를 통해 가독성을 높이려고 한 것 같아서 많이 배워갑니다. 리뷰하려고 들어왔는데 다른 분들의 리뷰덕분에 제가 배워가네요! 2주차 과제 고생많으셨어요!

}
}

private fun findWinners(): List<String> {

Choose a reason for hiding this comment

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

제가 MVC 패턴을 잘 몰라서 그러는데, findWinners나 moveCars는 동작이라서 model에서 다룰 수 없지 않나요?
제가 알기로 model은 순수하게 데이터베이스로만 사용하는걸로 알고있어서 여쭤봅니다.
Controller에서의 분리를 말씀하시는 건가요?

if (go) {
position++
}
}

Choose a reason for hiding this comment

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

위와 마찬가지의 질문인데,
model은 데이터베이스라서 순수하게 데이터만 들어가있어야 한다고 알고있거든요 그런데 위의 코드에는 함수가 있는데, 이렇게 함수가 포함된 model도 mvc를 지킨 모델인지 궁금합니다.

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.

5 participants