by در Kotlin چیه ؟ -توضیح ساده با رویکرد حل مسئله


کلمه کلیدی by یکی از کاربردی ترین مواردی هست که در زبان برنامه نویسی کاتلین اضافه شده و به برنامه نویس های اندرویدی کمک های زیادی میکنه.
توی این مقاله به طور مفصل میخوایم راجب این موضوع توضیح بدیم.
مقدمهای بر رویکرد اشتباه در آموزش برنامهنویسی
در یادگیری برنامهنویسی، به نظر من همیشه یه مورد خیلی اشتباه آموزش داده میشه. اون چیه؟
اینکه آموزشهای برنامهنویسی معمولاً فقط میان یه مفهوم رو توضیح میدن یا یه مشکل رو حل میکنن، ولی فرض رو بر این میذارن که مخاطب خودش اون مشکل رو میدونه. در حالیکه واقعاً دانشآموز یا کسی که آموزش میبینه، اصلاً ممکنه هیچ درکی از اون مشکل نداشته باشه. در نتیجه اون آموزش براش بیمعنی یا گنگ میشه یا مانند این سایت اصلی که خیلی کلی در این مورد by صحبت کرده .
مفهوم by هم یکی از همین مسئلههاست. پس ما توی این مطلب اول مشکل رو مطرح میکنیم، بعد راهحل رو با by ارائه میدیم.
سناریو اول : لاگ گرفتن و دیباگ کردن
توی این سناریو ما میخوام بدونیم متغییر های که داریم ، چه موقع مقدار دهی میشن ، کی استفاده میشن ، کی تغییر میکنند
اصلاً چرا باید بفهمیم یک متغیر داره چی میکنه؟
-
برای دیباگ کردن: بدونیم کی و کِی مقدار متغیر تغییر کرده.
-
برای ثبت لاگ یا رفتارهای کاربر: مثلاً لاگ بگیریم که کاربر کی اسمش رو تغییر داده.
-
برای کنترل بیشتر: مثلاً قبل از تغییر مقدار، اعتبارسنجی (validation) انجام بدیم.
-
برای معماری MVVM: توی معماریهایی مثل MVVM، وقتی مقدار state تغییر میکنه، باید UI آپدیت بشه. پس کنترل تغییر خیلی مهمه.
خلاصه:
بدون کنترل روی مقداردهی، برنامه غیرقابل پیشبینی میشه و دیباگ کردن سخت.
مرحله اول: تعریف مشکل
مثلاً ما یه متغیر معمولی تعریف میکنیم:
معرفی راهحل — استفاده از by و تعریف delegate اختصاصی
خب، تا اینجا دیدیم که اگر بخوایم رفتار خاصی (مثل ثبت لاگ یا نظارت بر تغییر مقدار) برای چندین متغیر بنویسیم، باید کلی getter/setter دستی تکراری بنویسیم. اینکار هم وقتگیره و هم کد رو زشت میکنه.
اینجاست که مفهوم delegation با by وارد میشه.
سناریوی دیگر: استفاده از by viewModels() در Android
من یه کلاس ویو مدل دارم ، ساختم و میخوام در کلاس خودم که فرگمنت یا اکتیویتی یا در کامپوز یه اسکرین هست استفاده کنم .
بدون by viewModels() — نوشتن دستی ViewModel
حالت اشتباهی که باعث بروز باگ میشه
فرض کن یه نفر اشتباهی بنویسه:
viewModel = ViewModelProvider(requireActivity()).get(ProfileViewModel::class.java)
در حالی که هدفش ViewModel scoped به Fragment بوده.
در این صورت ViewModel تا وقتی Activity زندهست باقی میمونه و این ممکنه:
-
باعث نشتی حافظه (Memory Leak) بشه.
-
یا باعث بشه data اشتباهی توی ViewModel باقی بمونه حتی بعد از destroy شدن Fragment.
class ProfileFragment : Fragment() {
private val viewModel: ProfileViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.loadProfile()
}
}
خیلی خلاصه ، بدون مشکل ، و تمیز . 😎
نتیجهگیری نهایی و بیان جدول های جمع بندی کی از by استفاده کنیم، کی نه؟
زمانهایی که استفاده از by مناسبه:
| کاربرد | توضیح |
|---|---|
| ✔ وقتی میخوای رفتاری مشترک برای چند property داشته باشی | مثل ثبت لاگ، اعتبارسنجی، نوتیفای کردن UI و… |
| ✔ وقتی میخوای lazy loading انجام بدی | مثلاً متغیری فقط وقتی نیاز شد ساخته بشه (by lazy) |
| ✔ وقتی میخوای تغییرات property رو مانیتور کنی | مثل observable یا vetoable |
| ✔ وقتی میخوای از کتابخونهها یا فریمورکها کمک بگیری | مثل by viewModels() در Jetpack یا by inject() در Koin |
| ✔ برای کم کردن کدهای تکراری و تمیز نگهداشتن کلاسها | همون چیزی که تو با LoggingDelegate ساختی |
زمانهایی که by استفاده نشه یا نیاز نیست:
| کاربرد | توضیح |
|---|---|
| ❌ وقتی فقط یک property ساده داری و هیچ رفتاری نیاز نیست | مثلاً یه var a = 5 ساده |
| ❌ وقتی نمیخوای کدی پنهان باشه یا Debug سخت بشه | delegate ممکنه رفتار پشتصحنه داشته باشه که برای بعضیها گنگه |
| ❌ وقتی نیاز به performance بسیار بالا داری و نمیخوای abstraction استفاده کنی | هر abstraction ممکنه یه سربار کوچیکی ایجاد کنه |
کلمهی by در Kotlin یک ابزار قدرتمنده که اجازه میده مسئولیت گرفتن یا ست کردن مقدار یک property رو به یک delegate بسپری. این باعث میشه:
-
کد تمیزتر بشه
-
تکرار کاهش پیدا کنه
-
رفتارهایی مثل لاگگیری، lazy loading و… خیلی راحت پیادهسازی بشن
-
اشتباهات انسانی در lifecycle مدیریت ViewModel و… کاهش پیدا کنه
پس همیشه به این فکر کن که آیا واقعاً به کنترل روی property نیاز داری یا نه. اگه نیاز داری، by میتونه بهترین دوستت باشه.
پایان 🥰







