굳이 sealed interface를 사용하는 이유?

SSY·2024년 5월 15일
0

Kotlin

목록 보기
9/11
post-thumbnail

시작하며

interface Top {
    data class Sub1(val ss: String): Top
    data class Sub2(val ss: String): Top
    data class Sub3(val ss: String): Top
    data object Sub4: Top
    class Sub5: Top
}

fun test(top: Top) {
    when (top) {
        is Top.Sub1 -> {}
        is Top.Sub2 -> {}
        is Top.Sub3 -> {}
    }
}

클래스를 계층화할 때, abstract classinterface가 있음에도 왜 sealed classsealed interface를 사용하는걸까?

단순, ViewModel에서 관습적으로 sealed interface를 사용해 상태관리를 하기에 무조건적으로 따라하다 갑자기 든 의문이었다. 충분히 일반적인 interfaceabstrace class로도 처리할 수 있는데 말이다.

이유? Compiler의 하위 타입 작성의 강제를 통한 앱 안정성 증가

이유는 하위 타입 클래스들이 추가 정의될 때, 컴파일러를 통해 오류를 잡기 위함이다. 위 코드의 Top인터페이스는 자식으로 5개의 클래스를 가지고 있다. 하지만 when문으로 분기처리할 때, 3개의 하위타입 지정했음에도 불구, 컴파일러가 에러를 지적해주지 않는다.

위와 같은 코드는 치명적인 약점이 있다.

  1. top아규먼트로 Sub4 또는 Sub5타입이 들어온다면, 앱이 크래시난다.
  2. Top인터페이스의 하위 타입이 추가될 때, 이에 맞는 하위 타입 처리를 어디에 해야할지 개발자가 놓칠 수 있다.
  3. else문으로 분기처리하여 진행 시, 앱 크래시는 막을 수 있다 쳐도, 정확한 하위 타입을 알 수 없다.

반면, Top인터페이스 선언에 sealed선언을 추가하면 위 문제가 모두 해결된다. 아래 when문을 보면 알겠지만, compiler가 빨간색 줄을 친절히 그어주고 있다. 이는 Top인터페이스 하위 자식이 when문에 모두 정의되어있지 않기에, 하위 타입을 모두 정의해달란 뜻이다.

위 처럼 compiler가 빨간 줄을 그어줄 땐, 앱 자체가 빌드 되지 않는다. 따라서 개발자가 자신의 실수를 쉽게 눈치채고 코드를 수정할 수 있게된다. 이에, Top.Sub4Top.Sub5를 추가하면 when문의 빨간 줄이 사라지는걸 볼 수 있다.

이러한 내용은 Kotlin공식 홈페이지에도 나와있다.

요약

abstract classinterface를 사용할 땐, when문을 사용한 하위 타입 분기처리를 놓침으로써 앱의 크래시 가능성을 배제할 수 없다. (이에 else문을 사용하는 것도 올바른 해결책이 아니다.)

하지만 sealed interface or sealed class는 compiler가 하위 타입 분기 로직 작성의 강제 및 에러를 표시해주므로 앱을 더 안전하게 해준다.

profile
불가능보다 가능함에 몰입할 수 있는 개발자가 되기 위해 노력합니다.

0개의 댓글

관련 채용 정보