Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
41be7a3
refactor: 패키지를 domain & view 로 분리
relkimm Nov 21, 2022
32edb84
refactor: CarName 글자수 검사 시 require 사용하도록 변경
relkimm Nov 21, 2022
3392656
feat: 기존 자동차를 통해 새로운 자동차 생성하는 로직 추가
relkimm Nov 21, 2022
ffe32fd
refactor: 자동차가 주행하고 나서 새로운 자동차를 반환하도록 수정
relkimm Nov 21, 2022
ccb8ca3
refactor: CarGroup 에서 자동차가 주행하더라도 불변하도록 수정
relkimm Nov 21, 2022
28acace
refactor: Store pub/sub 구조로 변경
relkimm Nov 21, 2022
ee967ec
feat: 라운드 관련 UI 를 표시하는 RoundComponent 추가
relkimm Nov 21, 2022
51ab1c0
refactor: Winner 를 표시하는 UI container/presentational 컴포넌트로 분리
relkimm Nov 21, 2022
b31626d
refactor: Round 를 표시하는 UI container/presentational 컴포넌트로 분리
relkimm Nov 21, 2022
e8b33e2
feat: 자동차 위치를 표시하는 UI container/presentational 컴포넌트 추가
relkimm Nov 21, 2022
81e58af
refactor: 불필요한 RoundResult 정리
relkimm Nov 21, 2022
459562a
refactor: RoundList 와 Round 를 표시하는 UI 분리
relkimm Nov 21, 2022
b4497de
refactor: DistanceComponent 네이밍 변경
relkimm Nov 21, 2022
a0bb3ab
refactor: 프로퍼티에는 this 붙이도록 수정
relkimm Nov 21, 2022
6aed63f
refactor: RoundContainer 에서 라운드 시작하는 로직 render 와 분리
relkimm Nov 21, 2022
3e6350e
feat: 자동차 이름 공백인 경우 유효성 검사 추가
relkimm Nov 21, 2022
133c53c
refactor: store 공통으로 사용할 수 있도록 개선
relkimm Nov 21, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions src/main/kotlin/racingcar/CarName.kt

This file was deleted.

5 changes: 5 additions & 0 deletions src/main/kotlin/racingcar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@
- [x] 경주 결과를 출력할 때 우승자도 같이 표시한다. pobi, honux가 최종 우승했습니다.
- [x] 우승자는 한명 이상이 될 수 있다.
- [x] 자동차 이름은 5자를 초과할 수 없다.
- [x] 패키지를 비즈니스 로직을 가지는 domain 패키지와 화면을 그리는 view 패키지로 나눈다.
- [ ] mvc 패턴 기반으로 리팩토링한다.
- [x] 기존의 자동차를 통해 새로운 자동차를 만들 수 있다.
- [x] 자동차는 move 이후 새로운 자동차를 반환한다.
-
6 changes: 3 additions & 3 deletions src/main/kotlin/racingcar/RacingGame.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package racingcar

import racingcar.component.CarNameInputComponent
import racingcar.component.RacingResultComponent
import racingcar.component.RoundInputComponent
import racingcar.view.component.CarNameInputComponent
import racingcar.view.component.RacingResultComponent
import racingcar.view.component.RoundInputComponent

object RacingGame {
fun run() {
Expand Down
9 changes: 0 additions & 9 deletions src/main/kotlin/racingcar/Round.kt

This file was deleted.

5 changes: 0 additions & 5 deletions src/main/kotlin/racingcar/RoundResult.kt

This file was deleted.

11 changes: 0 additions & 11 deletions src/main/kotlin/racingcar/component/CarNameComponent.kt

This file was deleted.

12 changes: 0 additions & 12 deletions src/main/kotlin/racingcar/component/DistanceComponent.kt

This file was deleted.

22 changes: 0 additions & 22 deletions src/main/kotlin/racingcar/component/RacingResultComponent.kt

This file was deleted.

11 changes: 0 additions & 11 deletions src/main/kotlin/racingcar/component/RoundOrderComponent.kt

This file was deleted.

16 changes: 0 additions & 16 deletions src/main/kotlin/racingcar/component/RoundResultComponent.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

class Car(
val id: Int,
Expand All @@ -7,9 +7,17 @@ class Car(
) {
var position = position
private set
fun move(movePolicy: MovePolicy) {

constructor(car: Car) : this(
id = car.id,
name = car.name,
position = car.position,
)

fun move(movePolicy: MovePolicy): Car {
if (movePolicy.canMove()) {
this.position = this.position.forward()
}
return Car(car = this)
Comment on lines +11 to +21
Copy link
Author

@relkimm relkimm Nov 21, 2022

Choose a reason for hiding this comment

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

immutable 하게 만들어 보았습니다~🙆‍♂️

Choose a reason for hiding this comment

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

새로운 car 객체를 잘 생성해주신 거 같은데요~
position 프로퍼티를 불변(val)으로 가지고 있어야 진정한 불변 객체가 아닐까 싶습니다! 🤔
현재는 car 객체의 position 값이 var 로 선언되어있네요~

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package racingcar
package racingcar.domain

import racingcar.dto.CarCreateDto
import racingcar.domain.dto.CarCreateDto

object CarFactory {
fun createMany(dtos: List<CarCreateDto>): List<Car> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package racingcar
package racingcar.domain

class CarGroup(private val cars: List<Car>) {
class CarGroup(private var cars: List<Car>) {
fun move() {
this.cars.forEach { car ->
this.cars = this.cars.map { car ->
val oil = OilStation.generateOilRandomly()
car.move(movePolicy = OilPolicy(oil = oil))
}
Comment on lines +3 to 8
Copy link
Author

@relkimm relkimm Nov 21, 2022

Choose a reason for hiding this comment

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

CarGroupmove 할 때도 immutable 하게 cars 를 반환할까 싶었는데!
아래 getPositions api 를 사용하는 것도 괜찮은 것 같아서 그대로 두었습니다.😭😭

Choose a reason for hiding this comment

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

CarGroup 이 move 할 때도 immutable 하게 cars 를 반환하는 것이 좀 더 안전한 프로그램 아닐까 싶은데요~ 🤔
getPositions() 를 호출하기 전까지 CarGroup 이 변경 불가능하다는 것을 보장받는 것이 전 좋아보입니다!

Expand Down
15 changes: 15 additions & 0 deletions src/main/kotlin/racingcar/domain/CarName.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package racingcar.domain

@JvmInline
value class CarName(
val value: String,
) {
init {
require(this.value.isNullOrBlank().not()) { "자동차 이름은 비어 있을 수 없습니다." }

Choose a reason for hiding this comment

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

마이너하지만 .not() 을 사용하게 되면서 가독성이 약간은 떨어지게 된 거 같아요~
아래와 같이 좀 더 간결하게 작성하는 것도 좋을 거 같습니다!

Suggested change
require(this.value.isNullOrBlank().not()) { "자동차 이름은 비어 있을 수 없습니다." }
require(this.value.isNotBlank()) { "자동차 이름은 비어 있을 수 없습니다." }

require(this.value.length <= MAX_NAME_LENGTH) { "자동차 이름은 5 글자를 초과할 수 없습니다." }
}
Comment on lines +4 to +10
Copy link
Author

Choose a reason for hiding this comment

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

자동차 이름이 비어있을 경우의 유효성 검사도 추가해 보았어요~

Choose a reason for hiding this comment

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

꼼꼼하게 피드백 반영해주셨네요~ 👍


companion object {
private const val MAX_NAME_LENGTH = 5
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

object CarNameSplitter {
private const val CAR_NAME_DELIMITER = ","
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

data class CarPosition private constructor(
val name: CarName,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

interface MovePolicy {
fun canMove(): Boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

@JvmInline
value class Oil(val amount: Int) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

class OilPolicy(
private val oil: Oil,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

object OilStation {
private val RANDOM_RANGE = (0..9)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

@JvmInline
value class Position(val value: Int) {
Expand Down
7 changes: 7 additions & 0 deletions src/main/kotlin/racingcar/domain/Round.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package racingcar.domain

class Round(val id: Int) {
fun start(carGroup: CarGroup) {
carGroup.move()
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

object RoundFactory {
fun createMany(amount: Int): List<Round> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package racingcar
package racingcar.domain

data class Winner(val name: CarName)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar
package racingcar.domain

object WinnerCalculator {
fun execute(cars: List<Car>): List<Car> {
Expand Down
7 changes: 7 additions & 0 deletions src/main/kotlin/racingcar/domain/dto/CarCreateDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package racingcar.domain.dto

import racingcar.domain.CarName

data class CarCreateDto(
val name: CarName,
)
7 changes: 0 additions & 7 deletions src/main/kotlin/racingcar/dto/CarCreateDto.kt

This file was deleted.

15 changes: 0 additions & 15 deletions src/main/kotlin/racingcar/store/CarGroupStore.kt

This file was deleted.

15 changes: 0 additions & 15 deletions src/main/kotlin/racingcar/store/RoundStore.kt

This file was deleted.

6 changes: 0 additions & 6 deletions src/main/kotlin/racingcar/store/Store.kt

This file was deleted.

12 changes: 12 additions & 0 deletions src/main/kotlin/racingcar/view/component/CarDistanceComponent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package racingcar.view.component

import racingcar.domain.Position
import racingcar.view.ui.Span

class CarDistanceComponent(
private val position: Position,
) : Component {
override fun render() {
repeat(this.position.value) { Span(text = "-").draw() }
}
}
11 changes: 11 additions & 0 deletions src/main/kotlin/racingcar/view/component/CarNameComponent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package racingcar.view.component

import racingcar.view.ui.Span

class CarNameComponent(
private val name: String,
) : Component {
override fun render() {
Span(text = "${this.name} : ").draw()
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package racingcar.component
package racingcar.view.component

import racingcar.CarFactory
import racingcar.CarGroup
import racingcar.CarName
import racingcar.CarNameSplitter
import racingcar.dto.CarCreateDto
import racingcar.store.CarGroupStore
import racingcar.ui.Input
import racingcar.ui.Span
import racingcar.domain.CarFactory
import racingcar.domain.CarGroup
import racingcar.domain.CarName
import racingcar.domain.CarNameSplitter
import racingcar.domain.dto.CarCreateDto
import racingcar.view.store.CarGroupStore
import racingcar.view.ui.Input
import racingcar.view.ui.Span

class CarNameInputComponent : Component {
private val span = Span(text = "경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).", block = true)
Expand Down
14 changes: 14 additions & 0 deletions src/main/kotlin/racingcar/view/component/CarPositionComponent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package racingcar.view.component

import racingcar.domain.CarPosition
import racingcar.view.ui.Br

class CarPositionComponent(private val carPositions: List<CarPosition>) : Component {
override fun render() {
this.carPositions.forEach { carPosition ->
CarNameComponent(name = carPosition.name.value).render()
CarDistanceComponent(position = carPosition.position).render()
Br().draw()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package racingcar.component
package racingcar.view.component

interface Component {
fun render()
Expand Down
11 changes: 11 additions & 0 deletions src/main/kotlin/racingcar/view/component/RacingResultComponent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package racingcar.view.component

import racingcar.view.container.RoundListContainer
import racingcar.view.container.WinnerContainer

class RacingResultComponent : Component {
override fun render() {
RoundListContainer().render()
WinnerContainer().render()
}
}
Loading