Когда используешь sealed class вместо enum?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Sealed Class vs Enum в Kotlin
Это отличный вопрос о выборе правильного инструмента для представления ограниченного набора типов. Хотя на первый взгляд они кажутся похожими, у каждого есть свои сценарии использования.
Что такое Enum?
Enum — это класс, который может иметь только фиксированное количество экземпляров. Каждое значение enum создаётся ровно один раз при загрузке класса.
enum class Status {
PENDING,
LOADING,
SUCCESS,
ERROR
}
Enum реализует Comparable и Enum интерфейсы, хранит порядок и может использоваться в when без else.
Что такое Sealed Class?
Sealed class — это абстрактный класс, который ограничивает подклассы только теми, что определены в том же файле или пакете. Подклассы могут быть:
- Другие sealed классы
- Обычные классы
- Data классы
- Objects
sealed class Result<T> {
data class Success<T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
object Loading : Result<Nothing>()
}
Ключевые различия
| Аспект | Enum | Sealed Class |
|---|---|---|
| Количество экземпляров | Ровно один на значение | Множество экземпляров подклассов |
| Данные | Только общие для всех | Каждый подкласс может иметь свои данные |
| Паттерн | Набор констант | Разные типы с разными свойствами |
| Производительность | Оптимальнее (singleton) | Требует создания объектов |
| Наследование | Не наследует другие классы | Может наследовать другие классы |
Когда использовать Enum
1. Фиксированный набор вариантов без дополнительных данных:
enum class Priority {
LOW,
MEDIUM,
HIGH,
CRITICAL
}
val taskPriority = Priority.HIGH
2. Состояния с одинаковой структурой:
enum class NetworkState {
CONNECTED,
DISCONNECTED,
UNKNOWN
}
3. Когда нужны константы с методами:
enum class Direction(val angle: Float) {
NORTH(0f),
EAST(90f),
SOUTH(180f),
WEST(270f);
fun opposite(): Direction = when(this) {
NORTH -> SOUTH
SOUTH -> NORTH
EAST -> WEST
WEST -> EAST
}
}
Когда использовать Sealed Class
1. Разные типы данных для разных состояний:
sealed class ViewState {
object Loading : ViewState()
data class Success(val data: List<Item>) : ViewState()
data class Error(val message: String, val code: Int) : ViewState()
data class Empty(val reason: String) : ViewState()
}
// Разные данные для разных состояний!
2. Результаты операций (Result/Either паттерн):
sealed class ApiResponse<T> {
data class Success<T>(val body: T, val headers: Map<String, String>) : ApiResponse<T>()
data class Error<T>(val code: Int, val message: String, val body: T? = null) : ApiResponse<T>()
data class NetworkError<T>(val exception: IOException) : ApiResponse<T>()
}
fun parseResponse(response: ApiResponse<User>) {
when(response) {
is ApiResponse.Success -> println(response.body)
is ApiResponse.Error -> println(response.message)
is ApiResponse.NetworkError -> println(response.exception)
}
}
3. UI события и действия:
sealed class UserAction {
data class ClickButton(val buttonId: Int) : UserAction()
data class EnterText(val text: String) : UserAction()
object ScrollToTop : UserAction()
data class SelectItem(val item: Any, val position: Int) : UserAction()
}
4. Иерархия типов:
sealed class Vehicle
data class Car(val doors: Int) : Vehicle()
data class Motorcycle(val hasSidecar: Boolean) : Vehicle()
data class Truck(val loadCapacity: Double) : Vehicle()
Практический пример: выбор инструмента
// ❌ Неправильно — enum для разных данных
enum class Result {
SUCCESS, // Но где хранить данные?
ERROR // Где хранить сообщение об ошибке?
}
// ✅ Правильно — sealed class
sealed class Result<T> {
data class Success<T>(val data: T) : Result<T>()
data class Error(val exception: Exception) : Result<Nothing>()
}
// ✅ Enum когда данные одинаковые
enum class HttpMethod {
GET,
POST,
PUT,
DELETE
}
Правило большого пальца
- Enum: много вариантов, одинаковая структура → HTTP методы, приоритеты, статусы
- Sealed class: разные варианты, разная структура и данные → результаты операций, UI события, иерархии типов
Выбор между ними определяется потребностями в хранении данных и гибкостью архитектуры.