Enum، Sealed و Generics؛ نظم برای حالتهای پیچیده
وقتی دادهها چند حالت مشخص دارن، نذار مثل گله گوسفند هرکدوم یه طرف برن.
Enum برای حالتهای ثابت
اگر چند مقدار ثابت داری، `enum class` بساز. مثلاً وضعیت سفارش: جدید، پرداختشده، ارسالشده. با رشته خام ننویس که یه جا `Paid` بزنی یه جا `Payed` و بعد سه روز دنبال باگ بگردی.
مثال را با چند مقدار دیگر هم امتحان کن؛ چون برنامهنویسی با نگاه کردن یاد گرفته نمیشود، با خراب کردن و درست کردن جا میافتد.
enum class OrderStatus {
NEW, PAID, SHIPPED, CANCELED
}
fun main() {
val status = OrderStatus.PAID
println(status)
}
PAID
Sealed class برای نتیجههای کنترلشده
`sealed class` وقتی خوبه که چند حالت محدود اما دادهدار داری؛ مثلاً Loading، Success، Error. عالی برای UI state و پاسخ API.
مثال را با چند مقدار دیگر هم امتحان کن؛ چون برنامهنویسی با نگاه کردن یاد گرفته نمیشود، با خراب کردن و درست کردن جا میافتد.
sealed class UiState {
object Loading : UiState()
data class Success(val data: String) : UiState()
data class Error(val message: String) : UiState()
}
fun render(state: UiState) = when (state) {
UiState.Loading -> "در حال بارگذاری..."
is UiState.Success -> "داده: ${state.data}"
is UiState.Error -> "خطا: ${state.message}"
}
اگر render(UiState.Success("OK")) را صدا بزنی:
داده: OKGenerics؛ جعبه برای هر نوع
جنریک یعنی تابع یا کلاس رو طوری بسازی که با نوعهای مختلف کار کنه. مثل جعبه ابزار حرفهای که فقط برای یک پیچ خاص ساخته نشده.
مثال را با چند مقدار دیگر هم امتحان کن؛ چون برنامهنویسی با نگاه کردن یاد گرفته نمیشود، با خراب کردن و درست کردن جا میافتد.
fun <T> printBox(value: T) {
println("[$value]")
}
fun main() {
printBox(123)
printBox("Kotlin")
}
[123] [Kotlin]
نتیجه این درس 🎯
Enum، sealed و generics سه ابزار برای کنترل حالتهای پیچیدهاند. با اینها کدت هم امنتر میشود هم whenها و مدلهای نتیجهات قابل اعتمادتر.
تمرین! 🧠
یک sealed class برای ApiResult بساز که Success و Failure داشته باشد و با when پیام مناسب چاپ کن.
sealed class ApiResult {
data class Success(val body: String) : ApiResult()
data class Failure(val error: String) : ApiResult()
}
fun message(result: ApiResult): String = when (result) {
is ApiResult.Success -> "موفق: ${result.body}"
is ApiResult.Failure -> "ناموفق: ${result.error}"
}
fun main() {
println(message(ApiResult.Success("OK")))
}
موفق: OK