[Effective Kotlin] 아이템 5. 예외를 활용해 코드에 제한을 걸어라

Jimin Lim·2023년 7월 16일
0

Effective Kotlin

목록 보기
5/39
post-thumbnail

아이템 5

예외를 활용해 코드에 제한을 걸어라

✅ 제한을 위한 코드블록 활용

  • requied 블록: 아규먼트 제한
  • check 블록: 상태와 관련된 동작 제한
  • assert 블록: 테스트모드에서 true 확인
  • return, throw와 함께 사용하는 Elvis 연산자
fun pop(num: Int = 1): List<T> {
	//아규먼트 제한	
    require(num <= size) {
        "Cannot remove more elements than current size"
    }
    //상태 동작 제한
    check(isopen) { "Cannot pop from closed stack" }
    val let = collection.take(num)
    collection = collection.drop(num)
    //true 확인
    assert(ret.size == num)
    return ret
}

위와 같이 제한을 하면, 다음과 같은 장점이 있다.

  1. 코드로 문서화
  2. 문제가 있다면 함수가 예상하지 못한 동작을 하지 않고 예외를 던진다.
  3. 코드가 어느정도 자체적으로 검사된다. -> 단위 테스트를 줄일 수 있음
  4. 스마트 캐스트 기능을 활용할 수 있게 되어, 캐스트를 적게 할 수 있다.

🔗 Require

input 에 대해 제한을 걸 수 있다. (ex. 숫자는 양의 정수, 이메일 주소 형식 판별)

fun factorial(n: Int): Long {
    require(n >= 0) { "Cannot calculate factorial of $n because it is smaller than 0" }
    return if (n <= 1) 1 else factorial(n - 1) * n
}

또한 IllegalArgumentException을 사용하므로 람다식을 사용해 메시지를 정의할 수 있다.

🔗 Check

구체적인 조건을 만족할 때만 함수를 사용할 수 있게 해야 할 때 사용한다. (ex. 객체가 미리 초기화되어 있어야만 처리, 사용자가 로그인했을 때만 처리)

Require과 유사하지만 IllegalStateException을 발생한다. 일반적으로 Require - Check의 순서다.

🔗 Assert

함수 내에서 로직이 참인지 확인할 때 사용한다.

fun pop(num: Int = 1): List<T> {
    // ...
    assert(ret.size == num) //java.lang.AssertionError: Assertion failed 발생
    return ret
}

-ea JVM옵션을 활성해야 확인할 수 있고, 테스트 할 때만 활성화 된다.

단위테스트 AssertThat와 비교해 좋은 점은 다음과 같다.

  • 특정 상황이 아닌 모든 상황에 대한 테스트를 할 수 있음
  • 실행 시점에 정확히 어떻게 되는지 확인 가능
  • 실제 코드가 더 빠른 시점에 실패

🔗 스마트 캐스팅

fun changeDress(person: Person) {
    require(person.outfit is Dress)
    val dress: Dress = person.outfit
}

require을 통과한 경우, person.outfit이 final이라면 Dress로 스마트 캐스팅된다.

특히 null 체킹에 유용한데, requireNotNull, checkNotNull을 사용해 null에 대한 스마트 캐스팅이 가능하다.

🔗 Elvis 연산자

elvis 연산자를 이용해 null인 경우 로그를 남기도록 하거나 throw로 예외를 던질 수 있다.

fun sendEmail(person: Person, text: String) {
    val email: String = person.email ?: run {
        log("Email not sent, no email address")
        return
    }
    // ...
}
profile
💻 ☕️ 🏝 🍑 🍹 🏊‍♀️

2개의 댓글

comment-user-thumbnail
2023년 7월 16일

잘봤습니다.

답글 달기
comment-user-thumbnail
2023년 7월 17일

저도 개발자인데 같이 교류 많이 해봐요 ㅎㅎ! 서로 화이팅합시다!

답글 달기