우아한테크코스

Lv1 자동차 경주 미션 피드백 2 : [우아한테크코스 5기 AN_베르]

베르_최성훈 2023. 2. 14. 00:20

이전 글에 이어서 현직자 분의 step2 리뷰 입니다.

반복되는 리뷰는 앞 글에서 묶어서 이미 정리하였습니다. 

1. 재사용 가능하게 만들어라 

class RaceTime(private var time: Int) {
    ...
   	fun reduceTime(): Boolean {
        if (time <= 0) {
            return false
        }
        time--
        return true
    }
    ...
}

위 코드에서 RaceTime 은 time 값이 0 이하가 되기 전까지 reduceTime 을 반복하여 time 변수를 외부에서 get하지 않아도 반복할 수 있다. 

하지만 이 RaceTime 객체를 재사용 하고 싶어도 이미 0이 되어버린 값은 돌릴 수 없는 문제가 생긴다.

이렇게 되면 의도치 않은 동작을 만들 수 있는 사이드 이펙트가 발생할 수도 있다.

 

해결한 방법 : 코틀린 고차함수를 사용하여 재사용이 가능하도록 만들었다.

 

- 고차함수 

  함수를 인자로 받거나 함수를 반환한다.

class RaceTime(private val time: Int) {
	...
 	fun repeatTimes(func: () -> Unit) {
        repeat(time) {
            func()
        }
    }
}

 

repeatTimes는 함수를 인자로 받아 time 만큼 반복한다. 컨트롤러에서 반복하고 싶은 함수를 전달한다.

기존 var time 은 이제 불변 변수 val 로 변경한다.

class Controller(){
private fun race(cars: List<Car>, raceTime: RaceTime) {
        outputView.printExecutionResult()
        raceTime.repeatTimes {
            raceOneTime(cars)
            outputView.printInterval()
        }
    }
}

 

2. 외부에서 사용 되는가?

class RaceTime(private val time:Int){
    init {
        validateRange()
    }

    private fun validateRange() {
        require(time in LOWER_RACE_TIME..UPPER_RACE_TIME) { ERROR_NOT_IN_RANGE }
    }

    companion object {
        const val LOWER_RACE_TIME = 1
        const val UPPER_RACE_TIME = 10
        
        const val ERROR_NOT_IN_RANGE = "시도 횟수는 1이상 10 이하여야 합니다."
    }
}

 위는 RaceTime 클래스로 time 을 받고 검증한다. 여기서 하드코딩을 없애기 위해 companion object를 사용했으나 RaceTime을 검증하기 위한 값이 외부에서 사용될 일은 없기 때문에 private으로 변경해 주는게 올바르다. 단, 에러 메세지는 테스트에서 사용하기 때문에 public으로 남겨두었다. 

    companion object {
        private const val LOWER_RACE_TIME = 1
        private const val UPPER_RACE_TIME = 10
        
        const val ERROR_NOT_IN_RANGE = "시도 횟수는 1이상 10 이하여야 합니다."
    }