본문 바로가기
Language/Kotlin

Sealed Class란 무엇인가?

by 시니성 2023. 10. 13.

Kotlin에서 sealed class는 한정된 클래스 상속을 제공하여 표현력 있는 도메인 모델을 구성할 수 있는 방법을 제공합니다. 즉, sealed class는 자신을 상속할 수 있는 클래스의 종류를 제한함으로써, 특정 상태와 행동을 더 명확하게 표현할 수 있습니다.

Sealed Class의 주요 특징

  1. 제한된 상속: Sealed 클래스의 모든 하위 클래스는 동일한 파일 내에 정의되어야 하므로 컴파일러가 가능한 모든 하위 타입을 알 수 있습니다.
  2. 상태 표현: Sealed 클래스는 앱의 명시적인 상태를 나타내는 데 사용될 수 있습니다. 각각의 하위 클래스는 앱의 상태의 일부 또는 전이를 나타냅니다.
  3. Exhaustive 체크: when 표현식에서 sealed 클래스를 사용하면, 모든 경우가 처리되었는지 컴파일러가 확인합니다. 만약 하위 클래스를 빠뜨리면 컴파일 에러를 받게 됩니다.

가상 시나리오: 주문 처리 시스템

하나의 주문이 처리되는 과정에서 여러 상태를 거칠 수 있습니다. 예를 들면, 주문이 생성되었다가 결제되고, 그 후에 배송되는 과정을 거치게 됩니다. 이런 상태 변화를 sealed class를 통해 표현해보겠습니다.

예시 코드

// 1. 기본적인 sealed class를 정의합니다. 이 클래스는 여러 하위 클래스를 가질 수 있습니다.
sealed class OrderState {
    // 2. 각각의 하위 클래스는 OrderState의 한 상태를 나타냅니다.
    object Created : OrderState()
    class Paid(val receipt: String) : OrderState()
    class Dispatched(val trackingNumber: String) : OrderState()
    object Delivered : OrderState()
    object Cancelled : OrderState()
}

// 3. 주문 클래스를 정의합니다.
data class Order(val id: String, val state: OrderState)

// 4. 주문의 상태를 변경하는 함수를 정의합니다.
fun processOrder(order: Order): String {
    // 5. when 표현식을 사용하여 각 상태를 처리합니다.
    return when (val state = order.state) {
        // 6. 각 상태마다 로직을 정의합니다.
        is OrderState.Created -> "Order ${order.id} is created."
        is OrderState.Paid -> "Order ${order.id} is paid. Receipt: ${state.receipt}"
        is OrderState.Dispatched -> "Order ${order.id} is dispatched with tracking number: ${state.trackingNumber}"
        is OrderState.Delivered -> "Order ${order.id} is delivered."
        is OrderState.Cancelled -> "Order ${order.id} is cancelled."
    }
}

코드 분석

  • 1단계: OrderState는 여러 상태를 가질 수 있는 sealed class입니다.
  • 2단계: OrderState의 각 하위 클래스는 주문의 가능한 한 상태를 나타냅니다. 어떤 상태는 추가 데이터를 가질 수 있습니다(예: Paid, Dispatched).
  • 3단계: Order 클래스는 id와 현재 상태를 가집니다.
  • 4단계: processOrder 함수는 주문을 처리하고 상태에 따른 메시지를 반환합니다.
  • 5 & 6단계: when 표현식은 각각의 상태를 체크하고 관련된 로직을 실행합니다. 만약 모든 상태가 처리되지 않으면 컴파일러는 오류를 반환합니다.

정리

sealed class를 사용하면 우리는 각각의 상태와 그에 따른 로직을 타입 안전하게 처리할 수 있습니다. 컴파일러가 모든 경우의 수를 검사하므로, 누락된 상태 처리에 대해 미리 알 수 있어 실수를 줄일 수 있습니다. 이를 통해 코드는 더 안전하고 이해하기 쉬워집니다.