Kotlin에서 sealed class
는 한정된 클래스 상속을 제공하여 표현력 있는 도메인 모델을 구성할 수 있는 방법을 제공합니다. 즉, sealed class
는 자신을 상속할 수 있는 클래스의 종류를 제한함으로써, 특정 상태와 행동을 더 명확하게 표현할 수 있습니다.
Sealed Class의 주요 특징
- 제한된 상속: Sealed 클래스의 모든 하위 클래스는 동일한 파일 내에 정의되어야 하므로 컴파일러가 가능한 모든 하위 타입을 알 수 있습니다.
- 상태 표현: Sealed 클래스는 앱의 명시적인 상태를 나타내는 데 사용될 수 있습니다. 각각의 하위 클래스는 앱의 상태의 일부 또는 전이를 나타냅니다.
- 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
를 사용하면 우리는 각각의 상태와 그에 따른 로직을 타입 안전하게 처리할 수 있습니다. 컴파일러가 모든 경우의 수를 검사하므로, 누락된 상태 처리에 대해 미리 알 수 있어 실수를 줄일 수 있습니다. 이를 통해 코드는 더 안전하고 이해하기 쉬워집니다.
728x90
'Language > Kotlin' 카테고리의 다른 글
InvocationTargetException (리플렉션을 통해 함수를 동적으로 실행할 시 예외 처리에 관한 글) (0) | 2024.06.26 |
---|---|
Java Virtual Machine(JVM) 메모리 옵션 분석 (0) | 2024.04.26 |
Event Sourcing을 통한 함수형 프로그래밍의 적용 (0) | 2023.10.13 |
코틀린에서의 `reduce` (0) | 2023.10.13 |
Kotlin에서의 기본 인자 값과 널 허용성 (0) | 2023.10.12 |