[Effective Kotlin] 아이템 7. 결과 부족이 발생할 경우 null, Failure를 사용하라

Jimin Lim·2023년 7월 16일
0

Effective Kotlin

목록 보기
7/39
post-thumbnail

아이템 7

결과 부족이 발생할 경우 null, Failure를 사용하라

✅ 예상치 못한 상황 발생

로직을 수행할 때, 원하는 결과를 만들어 낼 수 없는 경우가 있다.

예를 들어, 서버로 데이터를 읽어 들일 때 인터넷 연결 문제로 못읽음, 텍스트 파싱할 때 형식이 맞지 않음 등등..

이러한 상황을 처리할 때 (1) null, Failure 리턴, (2) 예외 throw 방식을 사용한다. 하지만 (2)의 경우 다음과 같은 문제점이 있다.

🔗 예외 문제점

일반적으로 예외는 정보를 전달하는 방법으로 사용해서는 안되고, 잘못된 특별한 상황을 나타내야 한다.

  • 많은 개발자가 예외가 전파되는 과정을 제대로 추적하지 못한다.
  • 코틀린의 모든 예외는 unchecked(처리하지 않아도 실행에 문제 없음) 예외다.
  • try-catch 블록 내부에 코드 배치하면 컴파일러가 할 수 있는 최적화가 제한된다.
  • 실행 중 전체 애플리케이션을 중지시킬 수 있다.

🔗 null, Failure 리턴

충분히 예측할 수 있는 범위의 오류는 null, Failure를 사용하고 예측하기 어려운 예외적인 범위의 오류는 throw가 낫다.

//null
inline fun <reified T> String.readObjectOrNull(): T? {
    // ...
    if (incorrectSign) {
        return null
    }
    // ...
    return result
}
//sealed Result
inline fun <reified T> String.readObject(): Result<T> {
    // ...
    if (incorrectSign) {
        return Failure(JsonParsingException())
    }
    // ...
    return Success(result)
}

sealed class Result<out T> //sealed는 컴파일러가 자식들을 알 수 있음 
class Success<out T>(val result: T): Result<T>()
class Failure(val throwable: Throwable): Result<Nothing>()
class JsonParsingException: Exception()

null/sealed Result로 return 한다면 다음과 같이 엘비스 연산자/when으로 오류를 간단히 잡을 수 있다. 전체 애플리케이션을 중지시킬 수 있는 예외보다 나은 방식이다.

val age = userText.readObjectOrNull<Person>()?.age ?: -1
val person = userText.readObjectOrNull<Person>()
val age = when(person) {
    is Success -> person.age
    is Failure -> -1
}

참고로 sealed Result는 추가적인 정보를 전달할 때 사용한다.

✅ 참고자료

https://bottom-to-top.tistory.com/69
sealed 관련: https://kotlinworld.com/165

profile
💻 ☕️ 🏝 🍑 🍹 🏊‍♀️

2개의 댓글

comment-user-thumbnail
2023년 7월 16일

잘봤습니다.

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

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

답글 달기