-
Notifications
You must be signed in to change notification settings - Fork 120
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* docs: 기능 목록 초기 작성 * feat: 최종 우승자 산출 기능 구현 * feat: 자동차 이름들 입력 기능 구현 * feat: 시도 횟수 입력 기능 구현 * refactor: 조건 숫자, 에러문구 상수화 * feat: 자동차 랜덤 전진 기능 구현 * test: 테스트 커밋 * feat: 실행 결과 출력 기능 구현 * feat: 최종 우승자 산출 기능 구현 * docs: 기능 목록 추가 * feat: 우승자 출력 기능 구현 * feat: 기능 통합 구현 * test: Car class 테스트 초기 작성 * test: Validator class 테스트 초기 작성 * test: Validator class 시도 횟수 입력 테스트 초기 작성 * test: RacingService class 객체 생성 테스트 작성 * feat: 고정 시드 랜덤 유틸 구현 * refactor: 랜덤 시작, 종료 범위, 이동 확률 상수화 * test: 최종 우승자 산출 테스트 코드 구현 * test: 최종 우승자 산출 테스트 코드 구현 * test: 자동차 생성 예외 테스트 코드 구현 * test: 최종 우승자 산출 예외 테스트 코드 구현 * test: 전체 기능 테스트 코드 구현 * feat: 공백 지우는 클래스 구현 * refactor: 메서드명, 길이 10자 이내로 제한하도록 리팩토링 * test: validator 테스트 코드 매개변수 수정 * docs: .gitkeep 파일 제거 * docs: .editorconfig 파일 마지막에 개행 문자 추가 * refactor: createCars() 메서드 반환값 표기 * refactor: ktlint에 맞춰 각 파일의 마지막 줄에 개행 문자 추가 * refactor: Car의 toString() 메서드 재정의 제거하고 name 프로퍼티에 접근할 수 있도록 수정 * refactor: Car 클래스의 getPositionAsDash() 메서드를 제거하고 position 프로퍼티에 접근할 수 있도록 수정 * refactor: Random 유틸 클래스를 제거하고 Service에서 로직 구현 * refactor: BlankRemover 유틸 클래스를 제거하고 Extensions 파일에서 처리하도록 수정 * fix: getRandomProbabilityInRange() 메서드의 Max bound 범위를 1 감소 * refactor: Dimens, Strings 파일에서 관리하던 상수를 필요한 클래스에서 관리하도록 수정 * test: testCarMovement() 메서드명을 testCarMovement()로 변경 * refactor: 불필요한 주석 및 코드 제거 * test: 자동차 객체 생성 테스트 코드 구현 * refactor: ApplicationKtTest 테스트 코드 분리하고 Given-When-Then 표기법으로 변경 * refactor: CarTest 네이밍을 Given-When-Then 표기법으로 변경 * refactor: RacingServiceTest 네이밍을 Given-When-Then 표기법으로 변경 * refactor: 자동차 이름의 길이를 Car 클래스 생성시 검증하도록 변경 * refactor: round 범위를 Round 래퍼 클래스에서 검증하도록 변경 * refactor: Round 범위 입력값의 숫자 여부 검증을 InputView에서 하도록 변경하고 일반화 * feat: CarRepository 클래스 구현 * feat: 자동차 중복 검증을 CarRepository에서 하도록 변경 * feat: 우승자 산출시 Car의 compareTo() 메서드로 비교하던 부분을 각 position 프로퍼티와 비교하도록 변경 * refactor: Dimens 파일에서 관리하던 상수를 필요한 클래스에서 관리하도록 수정 * refactor: getWinners() 메서드 매개변수 제거 * refactor: Round 객체 생성시 검증을 require 메서드를 사용하도록 변경 * test: 라운드 객체 생성 테스트 코드 구현 * fix: CarRepositry에서 car 객체 삽입시 검증을 위해 비교하는 기준을 이름으로 변경하여 에러 수정 * test: 자동차 moveCount 테스트에서 주어진 자동차 객체를 insert하도록 변경 * refactor: 불필요한 상수 제거 * refactor: getRandomProbabilityInRange() 메서드명 변경 * refactor: Car의 move() 메서드에 이동 조건값 추가 * test: Car 클래스의 move() 메서드 테스트 코드 구현 * fix: Car 클래스에서 이름 길이 검증시 throw를 두 번 발생시키는 버그 수정 * refactor: 자동차 이름 프로퍼티를 CarName 클래스로 분리 * refactor: Car 리스트를 Cars 클래스로 감싸서 RacingService에서 관리하도록 변경 * refactor: CarRepository 클래스 제거 * refactor: RacingController 클래스에서 RacingService 생성을 메서드로 분리 * refactor: removeBlank() 메서드에 반환 타입 표기 * feat: Winners 도메인 모델 구현 * refactor: 각 도메인 Model에 대해 DTO 구현 * refactor: RacingService에서 도메인 Model과 DTO를 변환하고 입출력시 Model 대신 DTO를 의존하도록 변경 * chore: kotlin("test") 라이브러리 제거 * chore: Mockito 2.21.0 라이브러리 추가 * refactor: Cars에서 randomGenerator를 주입받아 Car의 randomMove() 메서드의 인자로 이동할 확률을 넘기도록 수정 * refactor: CarName 객체 생성시 전달받은 이름에 대해 양 옆 공백을 제거하여 관리하도록 수정 * test: CarName 테스트 코드 구현 * test: Cars 자동차 이름 중복 검증 테스트 구현 * test: Cars getWinners() 테스트 코드 구현 * refactor: CarTest, RoundTest 패키지 이동 * refactor: runAllRounds 메서드 인자로 RoundDto 추가 * refactor: MovementProbabilityGenerator generate() 메서드 인자 제거 * refactor: Round 클래스 count 프로퍼티 접근제한자 private 제거 * test: RacingService 클래스 테스트 코드 구현 * refactor: 자동차 이동 확률 범위를 0에서 9로 변경 * refactor: Car model의 carName, position 프로퍼티를 var에서 val로 변경 * refactor: Car와 CarDto 변환을 mapper로 분리 * refactor: Cars와 CarsDto 변환을 mapper로 분리 * refactor: Winners와 WinnersDto 클래스 분리 * refactor: Round와 RoundDto 변환을 mapper로 분리 * refactor: CarName에서 name 프로퍼티가 _name을 trim()하여 반환하도록 변경 * refactor: CarName 클래스의 name 프로퍼티명을 value로 변경 * refactor: RandomGenerator 인터페이스명을 NumberGenerator로 변경 * chore: Mockito 라이브러리 제거 * chore: Mockito의 Mock 대신 fake객체를 사용하도록 변경 * refactor: MovementProbabilityGenerator 클래스를 제거하고 CarMoveCondition으로 변경 * refactor: MoveStep 인터페이스를 sealed 클래스로 변경 * refactor: CarMoveCondition 메서드를 operator invoke 메서드로 변경 * refactor: MoveStep 이동 거리 상수화 * fix: 매 라운드마다 자동차 위치 출력 안 되는 버그 수정 * refactor: Car move() 메서드 호출시 Step을 받도록 테스트 코드 변경 * refactor: Car moveAll에서 이동 여부 로직을 isSatisfyCondition() 메서드로 분리 * chore: CarRandomMoveCondtion Fake 클래스를 test 패키지로 이동
- Loading branch information
Showing
31 changed files
with
541 additions
and
319 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package racingcar.dto.car | ||
|
||
import racingcar.model.car.CarName | ||
|
||
class CarDto(_carName: String, val position: Int = 0) { | ||
val carName: CarName = CarName(_carName.trim()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package racingcar.dto.car | ||
|
||
class CarsDto(_cars: List<CarDto>) : List<CarDto> by _cars |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package racingcar.dto.car | ||
|
||
import racingcar.model.car.Car | ||
|
||
class WinnersDto(winners: List<Car>) : List<Car> by winners |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package racingcar.dto.round | ||
|
||
class RoundDto(val count: Int) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package racingcar.model.car | ||
|
||
import racingcar.model.car.move.step.MoveStep | ||
|
||
class Car(name: String, private var _position: Int = 0) { | ||
val carName: CarName = CarName(name) | ||
val position: Int get() = _position | ||
|
||
fun move(moveStep: MoveStep) { | ||
_position += moveStep.move() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package racingcar.model.car | ||
|
||
class CarName(private var _value: String) { | ||
val value: String get() = _value.trim() | ||
|
||
init { | ||
require(value.length in MIN_CAR_NAME_LENGTH..MAX_CAR_NAME_LENGTH) { | ||
CAR_NAME_LENGTH_OVER_BOUNDARY_ERROR_MESSAGE | ||
} | ||
} | ||
|
||
companion object { | ||
private const val MIN_CAR_NAME_LENGTH = 1 | ||
private const val MAX_CAR_NAME_LENGTH = 5 | ||
|
||
private const val CAR_NAME_LENGTH_OVER_BOUNDARY_ERROR_MESSAGE = | ||
"자동차 이름 길이의 범위는 $MIN_CAR_NAME_LENGTH 이상 $MAX_CAR_NAME_LENGTH 이하입니다." | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package racingcar.model.car | ||
|
||
import racingcar.model.car.move.condition.CarMoveCondition | ||
import racingcar.model.car.move.step.OneStep | ||
import racingcar.model.car.move.step.ZeroStep | ||
|
||
class Cars(_cars: List<Car>) : List<Car> by _cars { | ||
init { | ||
validateExistDuplicatedCarName() | ||
} | ||
|
||
private fun validateExistDuplicatedCarName() { | ||
val nonDuplicatedCarsForName = this.distinctBy { it.carName.value } | ||
|
||
require(this.size == nonDuplicatedCarsForName.size) { | ||
DUPLICATED_CAR_NAME_ERROR_MESSAGE | ||
} | ||
} | ||
|
||
fun moveAll(carMoveCondition: CarMoveCondition): Cars = this.onEach { car -> | ||
if (isSatisfyCondition(carMoveCondition)) { | ||
car.move(OneStep) | ||
} else { | ||
car.move(ZeroStep) | ||
} | ||
} | ||
|
||
private fun isSatisfyCondition(carMoveCondition: CarMoveCondition) = | ||
carMoveCondition() >= MOVE_CONDITION | ||
|
||
fun getWinners(): Winners { | ||
val winnerStandard = this.maxBy { it.position } | ||
return Winners(this.filter { it.position == winnerStandard.position }) | ||
} | ||
|
||
companion object { | ||
private const val DUPLICATED_CAR_NAME_ERROR_MESSAGE = | ||
"중복된 자동차 이름이 존재합니다." | ||
private const val MOVE_CONDITION = 4 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package racingcar.model.car | ||
|
||
import racingcar.dto.car.WinnersDto | ||
|
||
class Winners(winners: List<Car>) : List<Car> by winners { | ||
fun toDto(): WinnersDto = WinnersDto(this) | ||
} |
5 changes: 5 additions & 0 deletions
5
src/main/kotlin/racingcar/model/car/move/condition/CarMoveCondition.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package racingcar.model.car.move.condition | ||
|
||
interface CarMoveCondition { | ||
operator fun invoke(): Int | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/kotlin/racingcar/model/car/move/condition/CarRandomMoveCondition.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package racingcar.model.car.move.condition | ||
|
||
class CarRandomMoveCondition : CarMoveCondition { | ||
override operator fun invoke(): Int = | ||
(START_RANDOM_MOVEMENT_PROBABILITY..END_RANDOM_MOVEMENT_PROBABILITY).random() | ||
|
||
companion object { | ||
private const val START_RANDOM_MOVEMENT_PROBABILITY = 0 | ||
private const val END_RANDOM_MOVEMENT_PROBABILITY = 9 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package racingcar.model.car.move.step | ||
|
||
sealed class MoveStep { | ||
abstract fun move(): Int | ||
} | ||
|
||
object ZeroStep : MoveStep() { | ||
private const val ZERO_STEP = 0 | ||
|
||
override fun move(): Int = ZERO_STEP | ||
} | ||
|
||
object OneStep : MoveStep() { | ||
private const val ONE_STEP = 1 | ||
|
||
override fun move(): Int = ONE_STEP | ||
} |
2 changes: 1 addition & 1 deletion
2
src/main/kotlin/racingcar/model/Round.kt → ...ain/kotlin/racingcar/model/round/Round.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package racingcar.model | ||
package racingcar.model.round | ||
|
||
class Round(val count: Int) { | ||
init { | ||
|
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,27 @@ | ||
package racingcar.service | ||
|
||
import racingcar.model.Car | ||
import racingcar.repository.CarRepository | ||
import racingcar.repository.Repository | ||
import racingcar.dto.car.CarsDto | ||
import racingcar.dto.car.WinnersDto | ||
import racingcar.dto.round.RoundDto | ||
import racingcar.model.car.move.condition.CarMoveCondition | ||
import racingcar.model.car.move.condition.CarRandomMoveCondition | ||
import racingcar.utils.mapper.toDto | ||
import racingcar.utils.mapper.toModel | ||
|
||
class RacingService( | ||
private val carRepository: Repository<Car> = CarRepository() | ||
_cars: CarsDto, | ||
private val carMoveCondition: CarMoveCondition = CarRandomMoveCondition() | ||
) { | ||
fun getAll(): List<Car> = carRepository.selectAll() | ||
private val cars = _cars.toModel() | ||
|
||
fun insertCars(cars: List<Car>) { | ||
cars.forEach { insertCar(it) } | ||
fun runAllRounds(round: RoundDto, doEachRoundResult: (CarsDto) -> Unit) { | ||
repeat(round.toModel().count) { | ||
doEachRoundResult(moveCars()) | ||
} | ||
} | ||
|
||
private fun insertCar(car: Car) = carRepository.insert(car) | ||
private fun moveCars(): CarsDto = | ||
cars.moveAll(carMoveCondition).toDto() | ||
|
||
fun createCars(names: List<String>): List<Car> = | ||
names.map { Car(it) } | ||
|
||
fun moveRandomly(car: Car) { | ||
car.move(getRandomProbability()) | ||
} | ||
|
||
private fun getRandomProbability(): Int = | ||
(START_RANDOM_MOVEMENT_PROBABILITY..END_RANDOM_MOVEMENT_PROBABILITY).random() | ||
|
||
fun getWinners(): List<Car> { | ||
val cars = getAll() | ||
val winnerStandard = cars.maxBy { it.position } | ||
return cars.filter { it.position == winnerStandard.position } | ||
} | ||
|
||
companion object { | ||
private const val START_RANDOM_MOVEMENT_PROBABILITY = 1 | ||
private const val END_RANDOM_MOVEMENT_PROBABILITY = 10 | ||
} | ||
fun getWinners(): WinnersDto = cars.getWinners().toDto() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
package racingcar.utils | ||
|
||
fun List<String>.removeBlank() = map { it.trim() } | ||
fun List<String>.removeBlank(): List<String> = | ||
this.map { it.trim() } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package racingcar.utils.mapper | ||
|
||
import racingcar.dto.car.CarDto | ||
import racingcar.model.car.Car | ||
|
||
fun CarDto.toModel(): Car = Car(carName.value, position) | ||
|
||
fun Car.toDto(): CarDto = CarDto(carName.value, position) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package racingcar.utils.mapper | ||
|
||
import racingcar.dto.car.CarsDto | ||
import racingcar.model.car.Cars | ||
|
||
fun CarsDto.toModel(): Cars = Cars(this.map { it.toModel() }) | ||
|
||
fun Cars.toDto(): CarsDto = CarsDto( | ||
this.map { car -> car.toDto() } | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package racingcar.utils.mapper | ||
|
||
import racingcar.dto.round.RoundDto | ||
import racingcar.model.round.Round | ||
|
||
fun RoundDto.toModel(): Round = Round(count) |
Oops, something went wrong.