Sealed Class হল Kotlin-এ একটি বিশেষ ধরনের ক্লাস যা ইনহেরিটেন্স শ্রেণিবিন্যাসকে উপপ্রকারের একটি নির্দিষ্ট সেটে সীমাবদ্ধ করে। সমস্ত উপপ্রকার একই ফাইলে ঘোষণা করা হয় এবং কম্পাইলার জানেন, যা বাধ্যতামূলক else শাখা ছাড়াই একটি পূর্ণাঙ্গ when ব্লক ব্যবহারের অনুমতি দেয়। Kotlin Docs, 2026 অনুসারে, সিল করা ক্লাসগুলি সীমিত শ্রেণিবিন্যাস যেমন অবস্থা, ত্রুটির ধরন এবং UI ইভেন্ট উপস্থাপনের জন্য একটি গুরুত্বপূর্ণ প্রক্রিয়া।
মূল বিষয়
Sealed Class (সিল করা ক্লাস) হল Kotlin-এ একটি ক্লাস যা sealed মডিফায়ার দিয়ে চিহ্নিত। এটি একটি সীমিত টাইপ শ্রেণিবিন্যাস নির্ধারণ করে: সমস্ত সম্ভাব্য উপপ্রকার একই ফাইলে তালিকাভুক্ত এবং কম্পাইলার তাদের প্রতিটি সম্পর্কে জানে। এটি sealed class-কে সাধারণ ওপেন ক্লাস থেকে আলাদা করে যার উপপ্রকার যে কোনো জায়গায় ঘোষণা করা যেতে পারে।
Sealed class-এর মূল উদ্দেশ্য হল ভেরিয়েন্টের একটি সীমিত সেটের টাইপ-নিরাপদ উপস্থাপনা। প্রতিটি উপপ্রকারের নিজস্ব ডেটা কাঠামো থাকতে পারে, যা sealed class-কে enum-এর চেয়ে বেশি নমনীয় করে তোলে। রানটাইমে, sealed class একটি সাধারণ অ্যাবস্ট্রাক্ট ক্লাস; কম্পাইলার শুধুমাত্র কম্পাইল সময়ে সীমাবদ্ধতা আরোপ করে।
Sealed class বিশেষভাবে Android অ্যাপ আর্কিটেকচারে উপযোগী: UI অবস্থা, নেটওয়ার্ক অনুরোধের ফলাফল, Intents-এর মতো নেভিগেশন ইভেন্ট এবং অবশ্যই ত্রুটির শ্রেণিবিন্যাস — সাধারণ ব্যবহারের ক্ষেত্র।
কম্পাইল সময়ে, sealed class when এক্সপ্রেশনের জন্য জাম্প টেবিলে অপ্টিমাইজ করা হয়, যা এটিকে if-else চেইনের চেয়ে বেশি কার্যকর করে। data class-এর সাথে মিলিত হলে, প্রতিটি উপপ্রকার শুধু অবস্থাই নয় বরং মেথডও ধারণ করতে পারে, যা বয়লারপ্লেট কোড ছাড়াই স্ব-ডকুমেন্টিং ডোমেন মডেল তৈরি করতে দেয়।
Sealed class মোবাইল অ্যাপ্লিকেশনে স্টেট মেশিন উপস্থাপনের জন্যও কার্যকর। প্রতিটি অবস্থা অনন্য প্যারামিটারসহ একটি পৃথক উপপ্রকার, এবং অবস্থার মধ্যে রূপান্তর when এক্সপ্রেশনের মাধ্যমে নিয়ন্ত্রিত হয়। কম্পাইলার গ্যারান্টি দেয় যে সমস্ত সম্ভাব্য অবস্থা হ্যান্ডেল করা হয়েছে, UI অবস্থা বা বিজনেস লজিক পরিবর্তন করার সময় রানটাইম ত্রুটি দূর করে।
নতুন Kotlin ডেভেলপাররা প্রায়ই sealed class এবং enum-কে গুলিয়ে ফেলেন, কারণ উভয়ই মানের সেট সীমাবদ্ধ করে। তবে, তাদের মধ্যে মৌলিক পার্থক্য রয়েছে: enum হল একই ধরণের ধ্রুবকের একটি সেট, যেখানে sealed class বিভিন্ন ধরণের শ্রেণিবিন্যাস।
Enum সর্বোত্তম যখন সমস্ত ভেরিয়েন্ট অতিরিক্ত কাঠামো ছাড়াই ধ্রুবক হয়। উদাহরণস্বরূপ, সপ্তাহের দিন, অর্ডারের অবস্থা, বা প্যারামিটার ছাড়া কর্মের ধরণ। প্রতিটি enum মান একটি নির্দিষ্ট নামসহ সিঙ্গেলটন।
Sealed class প্রয়োজন যখন প্রতিটি ভেরিয়েন্টের নিজস্ব ডেটা থাকে। উদাহরণস্বরূপ, একটি নেটওয়ার্ক ত্রুটিতে প্রতিক্রিয়া কোড থাকে, একটি পার্সিং ত্রুটিতে বিবরণ থাকে, এবং একটি প্রমাণীকরণ ত্রুটিতে বার্তা থাকে। sealed class-এর প্রতিটি উপপ্রকার অনন্য ফিল্ডসহ একটি পৃথক ধরণ।
// Enum — একই ধরণের সব ভেরিয়েন্ট
enum class Status { LOADING, SUCCESS, ERROR }
// Sealed class — নিজস্ব ডেটাসহ প্রতিটি ভেরিয়েন্ট
sealed class UiState<out T> {
object Loading : UiState<Nothing>()
data class Success<T>(val data: T) : UiState<T>()
data class Error(val message: String) : UiState<Nothing>()
}
Kotlin 1.5 থেকে, sealed interface ঘোষণা করা সম্ভব। এটি সিল ধারণাটিকে ইন্টারফেসে প্রসারিত করে: sealed interface-এরও বাস্তবায়নের একটি নির্দিষ্ট সেট থাকে তবে এটি একাধিক ইনহেরিটেন্স সমর্থন করে।
Sealed interface সুবিধাজনক যখন উপপ্রকারগুলিকে একসাথে একাধিক চুক্তি বাস্তবায়ন করতে হয়। উদাহরণস্বরূপ, একটি UI ইভেন্ট একই সাথে ক্লিকযোগ্য এবং ট্র্যাকযোগ্য হতে পারে। sealed class-এর সাথে, আপনাকে একটি বেস ক্লাস বেছে নিতে হবে; sealed interface-এর সাথে, উপপ্রকার উভয়ই বাস্তবায়ন করে।
Sealed class একটি ক্লাস, তাই প্রতিটি উপপ্রকারের শুধুমাত্র একটি প্যারেন্ট থাকতে পারে। Sealed interface এই সমস্যার সমাধান করে কিন্তু অবস্থা ধারণ করতে পারে না। তাদের মধ্যে পছন্দ কাজের উপর নির্ভর করে: ফিল্ডসহ ভাগ করা লজিক প্রয়োজন — sealed class ব্যবহার করুন; চুক্তির নমনীয়তা প্রয়োজন — sealed interface ব্যবহার করুন।
sealed interface ScreenEvent {
data class Refresh(val force: Boolean) : ScreenEvent
data class Navigate(val route: String) : ScreenEvent
data class ShowError(val toast: String) : ScreenEvent
}
sealed interface AnalyticsEvent {
val name: String
val params: Map<String, Any>
}
// উপপ্রকার উভয় ইন্টারফেস বাস্তবায়ন করে
data class LoginClicked(
override val name: String = "login_click",
override val params: Map<String, Any> = emptyMap()
) : ScreenEvent, AnalyticsEvent
মোবাইল ডেভেলপমেন্টে sealed class-এর প্রধান ব্যবহারগুলির মধ্যে একটি হল টাইপ-নিরাপদ ত্রুটি শ্রেণিবিন্যাস। বিভিন্ন ধরণের এক্সেপশন নিক্ষেপ করার বা সাধারণ Exception ব্যবহার করার পরিবর্তে, sealed class সমস্ত সম্ভাব্য ডোমেন ত্রুটিকে একটি একক ধরণে সংগ্রহ করে।
একটি sealed class DomainError তৈরি করুন এবং সমস্ত ব্যর্থতার ধরণকে উপপ্রকার হিসাবে তালিকাভুক্ত করুন। প্রতিটি উপপ্রকারে শুধুমাত্র সেই ডেটা থাকে যা সেই নির্দিষ্ট ত্রুটির ধরণের জন্য প্রাসঙ্গিক। কম্পাইলার গ্যারান্টি দেয় যে ত্রুটি হ্যান্ডেল করার সময় আপনি কোনও ভেরিয়েন্ট ভুলবেন না।
একটি অ্যাপ বিবেচনা করুন যেখানে বিভিন্ন ব্যর্থতা পরিস্থিতি সম্ভব: ভুল পাসওয়ার্ড, অ্যাকাউন্ট ব্লক, সার্ভার সমস্যা। Sealed class সেগুলিকে পূর্ণাঙ্গ হ্যান্ডলিংসহ একটি একক ধরণে একত্রিত করে।
sealed class AuthError {
data class InvalidCredentials(
val attempts: Int
) : AuthError()
data class AccountBlocked(
val until: Long
) : AuthError()
data class NetworkFailure(
val cause: Throwable
) : AuthError()
object ServerError : AuthError()
}
fun handleError(error: AuthError): String = when (error) {
is AuthError.InvalidCredentials ->
"অবশিষ্ট প্রচেষ্টা: ${3 - error.attempts}"
is AuthError.AccountBlocked ->
"${Date(error.until)} পর্যন্ত অ্যাক্সেস ব্লক করা হয়েছে"
is AuthError.NetworkFailure ->
"সংযোগ পরীক্ষা করুন: ${error.cause.localizedMessage}"
AuthError.ServerError ->
"সার্ভার সাময়িকভাবে অনুপলব্ধ"
}
Sealed class Android অ্যাপ্লিকেশন আর্কিটেকচারে একটি মানক সরঞ্জাম হয়ে উঠেছে। আসুন তিনটি মূল প্যাটার্ন দেখি যেখানে sealed class মোবাইল ডেভেলপমেন্টে অপরিহার্য।
Clean Architecture-এ sealed class-এর ব্যবহারও উল্লেখযোগ্য। প্রতিটি স্তর (data, domain, presentation) তার ত্রুটির ধরণের জন্য sealed class ব্যবহার করে এবং ম্যাপাররা একটি sealed class-কে অন্যটিতে রূপান্তর করে। উদাহরণস্বরূপ, ডেটা স্তর থেকে DataError বিজনেস লজিকের জন্য DomainError-এ ম্যাপ হয় এবং তারপর প্রেজেন্টেশন স্তরের জন্য UiState-এ। এটি অ্যাপ্লিকেশনের সমস্ত স্তরে টাইপ সুরক্ষা সংরক্ষণ করে এবং গ্যারান্টি দেয় যে কোনও ত্রুটি অহ্যান্ডেল থাকে না।
পরীক্ষা করার জন্য sealed class-এর একটি বিশেষ পদ্ধতির প্রয়োজন, কারণ প্রতিটি উপপ্রকার নিজস্ব অবস্থাসহ একটি পৃথক ধরণ। প্যারামিটারাইজড টেস্ট লেখার পরামর্শ দেওয়া হয় যা sealed class-এর সমস্ত উপপ্রকারের উপর যায়। এটি গ্যারান্টি দেয় যে when এক্সপ্রেশনগুলি শ্রেণিবিন্যাস প্রসারিত করার সময় যোগ করা নতুনগুলি সহ সমস্ত ভেরিয়েন্ট কভার করে।
UI পরীক্ষার জন্য, sealed class কে UiState হিসাবে ব্যবহার করে প্রতিটি অবস্থার প্রদর্শন যাচাই করা যায়: Loading স্পিনার দেখায়, Content ডেটা দেখায়, Error ত্রুটি বার্তা দেখায়। যেহেতু sealed class সীমিত, সমস্ত অবস্থার টেস্ট কভারেজ UI লজিকের সঠিকতার উপর সম্পূর্ণ আস্থা দেয়।
ধারণাটির সরলতা সত্ত্বেও, ডেভেলপাররা নিয়মিত sealed class শ্রেণিবিন্যাস ডিজাইন করার সময় ভুল করে। আসুন মূল সমস্যা এবং সেগুলি এড়ানোর উপায় দেখি।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
হ্যাঁ, একটি sealed class-এ অ্যাবস্ট্রাক্ট মেথড থাকতে পারে, এবং প্রতিটি উপপ্রকার সেগুলি বাস্তবায়ন করতে বাধ্য। এটি সুবিধাজনক যখন সমস্ত ভেরিয়েন্টকে একটি সাধারণ ইন্টারফেস প্রদান করতে হবে কিন্তু ভিন্ন নির্বাহ লজিকসহ।
Java 17+-এ, sealed মডিফায়ারসহ সিল করা ক্লাস এবং ইন্টারফেস চালু হয়েছে। Android বর্তমানে Java 17 আংশিকভাবে সমর্থন করে, কিন্তু Kotlin প্রকল্পে, sealed class Kotlin 1.0 থেকে কোনও সীমাবদ্ধতা ছাড়াই উপলব্ধ।
হ্যাঁ, একটি sealed class অন্যটির উপপ্রকার হতে পারে। sealed class শ্রেণিবিন্যাস সীমিত থাকে: কম্পাইলার প্রতিটি স্তরে সমস্ত উপপ্রকার জানে। এটি বিস্তারিত ত্রুটি শ্রেণিবিন্যাস তৈরি করতে দেয়।
Sealed class রানটাইমে কোনও ওভারহেড তৈরি করে না। কম্পাইলার sealed class-সহ when এক্সপ্রেশনকে জাম্প টেবিলে (tableswitch) অপ্টিমাইজ করে, যা if-else চেইনের চেয়ে দ্রুত। কর্মক্ষমতা enum-এর সমান।
Sealed class-এর প্রতিটি উপপ্রকার পৃথকভাবে পরীক্ষা করা হয়। যেহেতু sealed class সীমিত, আপনি একটি প্যারামিটারাইজড টেস্ট লিখতে পারেন যা সমস্ত ভেরিয়েন্টের উপর যায়। এটি when ব্লকের শাখাগুলির সম্পূর্ণ কভারেজ দেয়।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন