🎯 میخوایم توی «Kotlin» بفهمیم که چطور «Variance» کار میکنه و «in» و «out» چطور از خطاهای تایپ جلوگیری میکنن.
🧠 فرض کن یه کلاس داری که فقط تولید میکنه (مثل «Producer») و یه کلاس دیگه که فقط مصرف میکنه (مثل «Consumer»). اگه «Variance» رو درست مدیریت نکنی، کامپایلر ارور میده.
💡 مثال واقعی: توی یک اپلیکیشن اندروید، یه لیست از آیتمهای مختلف داری که فقط باید بخونی (تولید) یا فقط بنویسی (مصرف). «in» و «out» توی «Generics» این کار رو برات آسون میکنن.
🧑💻 بیا با یه کد عملی ببینیم:
📌 کد بالا رو توضیح بدم:
-
-
- این کار باعث میشه از ارورهای تایپ در زمان کامپایل جلوگیری بشه و کدت انعطافپذیرتر بشه.
🎯 نکته عملی: وقتی از «LiveData» یا «StateFlow» استفاده میکنی، خروجیشون «out» هست (فقط خواندنی) و ورودی توی «Room» میتونه «in» باشه. این رو توی پروژههات رعایت کن.
🔥 با تسلط به «Variance» کدهای «Kotlin»ت نوعمحور و خطاناپذیرتر میشن.
#Codeit #Kotlin #Android #Jetpack #Generics #Covariance #Contravariance
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🧠 فرض کن یه کلاس داری که فقط تولید میکنه (مثل «Producer») و یه کلاس دیگه که فقط مصرف میکنه (مثل «Consumer»). اگه «Variance» رو درست مدیریت نکنی، کامپایلر ارور میده.
💡 مثال واقعی: توی یک اپلیکیشن اندروید، یه لیست از آیتمهای مختلف داری که فقط باید بخونی (تولید) یا فقط بنویسی (مصرف). «in» و «out» توی «Generics» این کار رو برات آسون میکنن.
🧑💻 بیا با یه کد عملی ببینیم:
// تعریف یک کلاس والد و دو کلاس فرزند
open class Animal
class Dog : Animal()
class Cat : Animal()
// Producer فقط خروجی میده (covariant)
class Producer<out T>(private val item: T) {
fun produce(): T = item
}
// Consumer فقط ورودی میگیره (contravariant)
class Consumer<in T> {
fun consume(item: T) {
println("Consuming: $item")
}
}
fun main() {
val dogProducer: Producer<Dog> = Producer(Dog())
val animalProducer: Producer<Animal> = dogProducer // مجازه چون out است
val animal: Animal = animalProducer.produce()
val animalConsumer: Consumer<Animal> = Consumer()
val dogConsumer: Consumer<Dog> = animalConsumer // مجازه چون in است
dogConsumer.consume(Dog())
}
📌 کد بالا رو توضیح بدم:
-
Producer<out T> یعنی نوع T فقط توی خروجی استفاده میشه، پس Producer<Dog> رو میتونی به Producer<Animal> نسبت بدی (covariance).-
Consumer<in T> یعنی نوع T فقط توی ورودی استفاده میشه، پس Consumer<Animal> رو میتونی به Consumer<Dog> نسبت بدی (contravariance).- این کار باعث میشه از ارورهای تایپ در زمان کامپایل جلوگیری بشه و کدت انعطافپذیرتر بشه.
🎯 نکته عملی: وقتی از «LiveData» یا «StateFlow» استفاده میکنی، خروجیشون «out» هست (فقط خواندنی) و ورودی توی «Room» میتونه «in» باشه. این رو توی پروژههات رعایت کن.
🔥 با تسلط به «Variance» کدهای «Kotlin»ت نوعمحور و خطاناپذیرتر میشن.
#Codeit #Kotlin #Android #Jetpack #Generics #Covariance #Contravariance
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
🔥 استثناها رو قورت نده! مدیریت حرفهای خطاها با «try» و «catch» در «Kotlin» 🚀
برنامهنویس حرفهای کسی نیست که بدون خطا کد بزنه، کسیست که میدونه چطور با خطاها برخورد کنه. توی «Kotlin» مدیریت استثناها با «try-catch» ساده و قدرتمنده.
❌ تصور کن کاربر متنی رو وارد کنه که عدد نیست و برنامه کرش کنه! این اصلاً حرفهای نیست.
✅ باید پیشبینی کنی که ممکنه خطا رخ بده و با «try-catch» کنترلش کنی.
📌 کاربرد واقعی: وقتی از کاربر ورودی میگیری، حتماً از «try-catch» برای تبدیل امن استفاده کن.
مثال عملی: عدد از کاربر بگیر و اگر اشتباه وارد کرد، خطا رو مدیریت کن:
این تابع اگر کاربر عدد وارد نکنه، به جای کرش، پیام خطا چاپ میکنه و null برمیگردونه. بعدش میتونی با شرط بررسی کنی.
💡 نکته مهم: همیشه «catch» رو برای نوع خاصی از استثنا بنویس، نه همه خطاها. از «Exception» عمومی فقط در مواقع ضروری استفاده کن.
🎯 نتیجه: کدت پایدارتر میشه، کاربر تجربه بهتری داره و دیباگ راحتتره.
#Codeit #Android #Kotlin #ExceptionHandling #TryCatch #CleanCode #ProgrammingTips
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
برنامهنویس حرفهای کسی نیست که بدون خطا کد بزنه، کسیست که میدونه چطور با خطاها برخورد کنه. توی «Kotlin» مدیریت استثناها با «try-catch» ساده و قدرتمنده.
❌ تصور کن کاربر متنی رو وارد کنه که عدد نیست و برنامه کرش کنه! این اصلاً حرفهای نیست.
✅ باید پیشبینی کنی که ممکنه خطا رخ بده و با «try-catch» کنترلش کنی.
📌 کاربرد واقعی: وقتی از کاربر ورودی میگیری، حتماً از «try-catch» برای تبدیل امن استفاده کن.
مثال عملی: عدد از کاربر بگیر و اگر اشتباه وارد کرد، خطا رو مدیریت کن:
fun readNumber(): Int? {
return try {
val input = readLine()
input?.toInt()
} catch (e: NumberFormatException) {
println("❌ ورودی معتبر نیست، لطفاً عدد وارد کنید.")
null
}
}
این تابع اگر کاربر عدد وارد نکنه، به جای کرش، پیام خطا چاپ میکنه و null برمیگردونه. بعدش میتونی با شرط بررسی کنی.
💡 نکته مهم: همیشه «catch» رو برای نوع خاصی از استثنا بنویس، نه همه خطاها. از «Exception» عمومی فقط در مواقع ضروری استفاده کن.
🎯 نتیجه: کدت پایدارتر میشه، کاربر تجربه بهتری داره و دیباگ راحتتره.
#Codeit #Android #Kotlin #ExceptionHandling #TryCatch #CleanCode #ProgrammingTips
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
کد خواناتر یعنی احترام به خودِ آیندهات 😎
خوانایی فقط ظاهر نیست؛ روی سرعت توسعه و دیباگ تأثیر مستقیم داره.
وقتی کدت رو برای دیگران (و خودت) روشن مینویسی، اشکالزدایی نصف میشه.
توی پروژههای تیمی، کد نامفهوم باعث سردرگمی و اتلاف وقت میشه.
با نامگذاری خوب و توابع کوتاه، همه برندهاند.
یک مثال ساده از تفاوت کد بد و خوب:
تابع اول با اسمهای تکحرفی و ساختار فشرده، فهمش سخته.
دومی با اسم معنادار و استفاده از «filter» و «sum» در یک خط، هدف رو واضح میکنه.
همیشه قبل از نوشتن کد به این فکر کن که آیا ۶ ماه بعد متوجهاش میشی؟
اگر نه، بازنویسی کن. همین یک عادت، کیفیت کارت رو چند برابر میکنه 🚀
#Codeit #Android #Kotlin #Jetpack #CleanCode #Readability #DeveloperMindset
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
خوانایی فقط ظاهر نیست؛ روی سرعت توسعه و دیباگ تأثیر مستقیم داره.
وقتی کدت رو برای دیگران (و خودت) روشن مینویسی، اشکالزدایی نصف میشه.
توی پروژههای تیمی، کد نامفهوم باعث سردرگمی و اتلاف وقت میشه.
با نامگذاری خوب و توابع کوتاه، همه برندهاند.
یک مثال ساده از تفاوت کد بد و خوب:
// کد غیرقابل خواندن
fun a(b: List<Int>): Int { var c = 0; for (d in b) { if (d > 0) c += d }; return c }
// کد خوانا
fun sumPositiveNumbers(numbers: List<Int>): Int {
return numbers.filter { it > 0 }.sum()
}
تابع اول با اسمهای تکحرفی و ساختار فشرده، فهمش سخته.
دومی با اسم معنادار و استفاده از «filter» و «sum» در یک خط، هدف رو واضح میکنه.
همیشه قبل از نوشتن کد به این فکر کن که آیا ۶ ماه بعد متوجهاش میشی؟
اگر نه، بازنویسی کن. همین یک عادت، کیفیت کارت رو چند برابر میکنه 🚀
#Codeit #Android #Kotlin #Jetpack #CleanCode #Readability #DeveloperMindset
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1👍1🔥1
🔒 تو کد نویسی، بعضی عملیاتها رو باید حتماً تموم کنی حتی اگه خطا بیاد!
«Finally block» در «Kotlin» دقیقاً همین کار رو میکنه.
📌 کاربرد اصلی: بستن فایل، قطع connection یا آزاد کردن حافظه
مهم نیست خطا رخ بده یا نه، کد داخل «finally» همیشه اجرا میشه.
💡 مثال واقعی: فرض کن داری فایل میخونی؛ اگه خطا هم بیاد، فایل باید بسته بشه.
یک نمونه ساده از ترکیب try-catch-finally:
🧠 این کد نشون میده که حتی در صورت خطا،
توی پروژههای واقعی، مثلاً
🎯 نکته مهم: اگر داخل
پس برای مدیریت مطمئن منابع، هیچ جایگزینی باحالتر از «finally block» نیست!
#Codeit #Android #Kotlin #Jetpack #ExceptionHandling #CleanCode #FinallyBlock
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
«Finally block» در «Kotlin» دقیقاً همین کار رو میکنه.
📌 کاربرد اصلی: بستن فایل، قطع connection یا آزاد کردن حافظه
مهم نیست خطا رخ بده یا نه، کد داخل «finally» همیشه اجرا میشه.
💡 مثال واقعی: فرض کن داری فایل میخونی؛ اگه خطا هم بیاد، فایل باید بسته بشه.
یک نمونه ساده از ترکیب try-catch-finally:
fun readFile(path: String): String? {
val file = File(path)
return try {
file.readText()
} catch (e: IOException) {
println("خطا در خواندن فایل: ${e.message}")
null
} finally {
println("✅ فایل حتماً بسته میشه (در عمل اینجا close داریم)")
}
}
🧠 این کد نشون میده که حتی در صورت خطا،
finally اجرا شده و پیام چاپ میشه. توی پروژههای واقعی، مثلاً
close() رو توی finally میذارن تا منبع نشتی نداشته باشه. 🎯 نکته مهم: اگر داخل
try یا catch از return استفاده کنی، بازم finally قبل از برگشت اجرا میشه. پس برای مدیریت مطمئن منابع، هیچ جایگزینی باحالتر از «finally block» نیست!
#Codeit #Android #Kotlin #Jetpack #ExceptionHandling #CleanCode #FinallyBlock
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤2👍1🔥1
🔹 توی پروژههای واقعی، خطاها رو با «Exception» استاندارد جاوا مدیریت نکن! 🚫
🔸 بیا ببینیم چطور «Custom Exception»های اختصاصی توی «Kotlin» بسازیم که دیباگ و نگهداری کد رو خیلی راحتتر کنه.
🔹 فرض کن داری یک اپ پرداخت مینویسی. بهجای اینکه هر بار «IllegalArgumentException» پرت کنی، یک «InsufficientBalanceException» بساز که دقیقاً بگه مشکل چیه. ✅
🔸 این کار خوانایی خطاها رو بالا میبره و توی «Log»ها دقیقاً میفهمی کجا خطا رخ داده.
🔹 یک مثال ساده از «Custom Exception» در «Kotlin»:
🔸 این کد یک «Exception» سفارشی با دو ویژگی عددی میسازه و پیام خطا رو خودش تولید میکنه. توی تابع پرداخت هم اگر موجودی کم باشه، این خطا پرتاب میشه.
🔹 نکته مهم: میتونی توی «Custom Exception» متدها یا پراپرتیهای اضافه هم تعریف کنی. مثلاً یک متد برای لاگکردن جزئیات خطا.
🔸 حالا توی کد اصلی میتونی با «try-catch» دقیقاً این نوع خطا رو بگیر و پیام مناسب به کاربر نشون بدی.
🔹 خلاصه: «Custom Exception» بهت کمک میکنه کدت خواناتر، قابل نگهداریتر و حرفهایتر باشه. همین امروز توی پروژههات استفاده کن! 🚀
#Codeit #Android #Kotlin #Jetpack #CleanCode #Exceptions #KotlinTips
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🔸 بیا ببینیم چطور «Custom Exception»های اختصاصی توی «Kotlin» بسازیم که دیباگ و نگهداری کد رو خیلی راحتتر کنه.
🔹 فرض کن داری یک اپ پرداخت مینویسی. بهجای اینکه هر بار «IllegalArgumentException» پرت کنی، یک «InsufficientBalanceException» بساز که دقیقاً بگه مشکل چیه. ✅
🔸 این کار خوانایی خطاها رو بالا میبره و توی «Log»ها دقیقاً میفهمی کجا خطا رخ داده.
🔹 یک مثال ساده از «Custom Exception» در «Kotlin»:
class InsufficientBalanceException(
val currentBalance: Double,
val requiredAmount: Double
) : Exception("موجودی کافی نیست. موجودی: $currentBalance، نیاز: $requiredAmount")
fun processPayment(amount: Double, balance: Double) {
if (amount > balance) {
throw InsufficientBalanceException(balance, amount)
}
println("پرداخت با موفقیت انجام شد")
}
🔸 این کد یک «Exception» سفارشی با دو ویژگی عددی میسازه و پیام خطا رو خودش تولید میکنه. توی تابع پرداخت هم اگر موجودی کم باشه، این خطا پرتاب میشه.
🔹 نکته مهم: میتونی توی «Custom Exception» متدها یا پراپرتیهای اضافه هم تعریف کنی. مثلاً یک متد برای لاگکردن جزئیات خطا.
🔸 حالا توی کد اصلی میتونی با «try-catch» دقیقاً این نوع خطا رو بگیر و پیام مناسب به کاربر نشون بدی.
🔹 خلاصه: «Custom Exception» بهت کمک میکنه کدت خواناتر، قابل نگهداریتر و حرفهایتر باشه. همین امروز توی پروژههات استفاده کن! 🚀
#Codeit #Android #Kotlin #Jetpack #CleanCode #Exceptions #KotlinTips
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
🎯 الگوی «Result» در «Kotlin» یکی از تمیزترین روشهای مدیریت خطاست
بدون نیاز به try-catchهای زنجیرهای و گیجکننده 🔁
🔥 چرا «Result Pattern»؟
- موفقیت یا شکست رو بهصورت صریح برمیگردونه
- کد خواناتر و قابل پیشبینیتر میشه
- ترکیبپذیری با «sealed class» و «when» بینظیره
📱 مثال واقعی: گرفتن اطلاعات کاربر از سرور با «Retrofit»
🧠 این کد چه میکند؟
- یک «sealed class» به نام «NetworkResult» تعریف میکند
- در صورت موفقیت شیء «Success» و در صورت خطا شیء «Error» برمیگرداند
- با «when» هر حالت رو جداگانه مدیریت میکنیم؛ هیچ خطایی از قلم نمیافته
💡 نکته عملی:
این الگو با «Coroutines» و «Flow» هم عالی کار میکنه
برای مدیریت خطاهای محلی و سراسری در «ViewModel» میتونی ازش استفاده کنی
📌 خلاصه: «Result Pattern» = کد مقاومتر + اشکالزدایی آسانتر
#Codeit #Android #Kotlin #Jetpack #ResultPattern #CleanArchitecture #SealedClass #ErrorHandling
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
بدون نیاز به try-catchهای زنجیرهای و گیجکننده 🔁
🔥 چرا «Result Pattern»؟
- موفقیت یا شکست رو بهصورت صریح برمیگردونه
- کد خواناتر و قابل پیشبینیتر میشه
- ترکیبپذیری با «sealed class» و «when» بینظیره
📱 مثال واقعی: گرفتن اطلاعات کاربر از سرور با «Retrofit»
sealed class NetworkResult<out T> {
data class Success<T>(val data: T) : NetworkResult<T>()
data class Error(val message: String, val exception: Throwable? = null) : NetworkResult<Nothing>()
}
suspend fun fetchUser(): NetworkResult<User> {
return try {
val user = api.getUser() // فراخوانی شبکه
NetworkResult.Success(user)
} catch (e: Exception) {
NetworkResult.Error("خطا در دریافت داده", e)
}
}
// استفاده
when (val result = fetchUser()) {
is NetworkResult.Success -> showUser(result.data)
is NetworkResult.Error -> showError(result.message)
}
🧠 این کد چه میکند؟
- یک «sealed class» به نام «NetworkResult» تعریف میکند
- در صورت موفقیت شیء «Success» و در صورت خطا شیء «Error» برمیگرداند
- با «when» هر حالت رو جداگانه مدیریت میکنیم؛ هیچ خطایی از قلم نمیافته
💡 نکته عملی:
این الگو با «Coroutines» و «Flow» هم عالی کار میکنه
برای مدیریت خطاهای محلی و سراسری در «ViewModel» میتونی ازش استفاده کنی
📌 خلاصه: «Result Pattern» = کد مقاومتر + اشکالزدایی آسانتر
#Codeit #Android #Kotlin #Jetpack #ResultPattern #CleanArchitecture #SealedClass #ErrorHandling
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
دیسیپلین یعنی خوابت میاد ولی بلند میشی!
دیسیپلین یعنی این کار باید انجام بشه. . .
دیسیپلین یعنی من آرزوشو ندارم من به دستش میارم!
دیسیپلین یعنی دلم پیتزا میخواد ولی دارم تخم مرغ آبپز میخورم!
دیسیپلین یعنی تفریحو عقب میندازی چون الان وقت ساختنه...
دیسیپلین یعنی خودتو به برنامهت متعهد بدونی نه به بهونه هات !
دیسیپلین یعنی مدیریت خودت حتی وقتی هیچ کس نمیبینه
دیسیپلین یعنی تکرار تکرار تکرار...
@CodeitMobile
دیسیپلین یعنی این کار باید انجام بشه. . .
دیسیپلین یعنی من آرزوشو ندارم من به دستش میارم!
دیسیپلین یعنی دلم پیتزا میخواد ولی دارم تخم مرغ آبپز میخورم!
دیسیپلین یعنی تفریحو عقب میندازی چون الان وقت ساختنه...
دیسیپلین یعنی خودتو به برنامهت متعهد بدونی نه به بهونه هات !
دیسیپلین یعنی مدیریت خودت حتی وقتی هیچ کس نمیبینه
دیسیپلین یعنی تکرار تکرار تکرار...
@CodeitMobile
❤2🔥1
🚀 قدرت «Code Review» را دست کم نگیرید!
بازبینی کد فقط پیدا کردن باگ نیست؛ یک فرصت طلایی برای رشد فردی و تیمی است.
خیلی از توسعهدهندهها از «Code Review» فرار میکنند، اما حقیقت این است که این فرآیند، کیفیت کد و اعتماد به نفس تیمی را چند برابر میکند.
📌 چرا «Code Review» مهم است؟
- یادگیری سریعتر: با دیدن کد دیگران، تکنیکهای جدید یاد میگیرید.
- کاهش باگ: یک جفت چشم دیگر، اشتباهات را زودتر میگیرد.
- یکدست شدن کد: تیم به یک سبک واحد میرسد.
🎯 مثال واقعی:
یک تیم اندروید باگ بحرانیای در بخش پرداخت داشت. بعد از اضافه کردن «Code Review» اجباری، تعداد باگهای تولید ۷۰٪ کاهش یافت.
🧠 نکته ذهنی:
هنگام بازبینی، به جای «اشتباه کردی» بگویید «اینجا ممکنه مشکل ایجاد کنه، راه حل جایگزین فلان است؟». این کار فرهنگ بازخورد سازنده را میسازد.
💡 چطور شروع کنیم؟
- برای هر «Pull Request» حداقل ۱۵ دقیقه وقت بگذارید.
- سوال بپرسید، نه حکم.
- از تیکهای «LGTM» (Looks Good To Me) بیدلیل استفاده نکنید.
📈 نتیجه نهایی:
«Code Review» نه یک تشریفات، بلکه سرمایهگذاری روی کیفیت و یادگیری تیم است. اگر امروز شروع کنید، یک ماه دیگر تفاوت را حس میکنید.
#Codeit #Android #Kotlin #Jetpack #CodeReview #CleanCode #DeveloperGrowth #Teamwork
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
بازبینی کد فقط پیدا کردن باگ نیست؛ یک فرصت طلایی برای رشد فردی و تیمی است.
خیلی از توسعهدهندهها از «Code Review» فرار میکنند، اما حقیقت این است که این فرآیند، کیفیت کد و اعتماد به نفس تیمی را چند برابر میکند.
📌 چرا «Code Review» مهم است؟
- یادگیری سریعتر: با دیدن کد دیگران، تکنیکهای جدید یاد میگیرید.
- کاهش باگ: یک جفت چشم دیگر، اشتباهات را زودتر میگیرد.
- یکدست شدن کد: تیم به یک سبک واحد میرسد.
🎯 مثال واقعی:
یک تیم اندروید باگ بحرانیای در بخش پرداخت داشت. بعد از اضافه کردن «Code Review» اجباری، تعداد باگهای تولید ۷۰٪ کاهش یافت.
🧠 نکته ذهنی:
هنگام بازبینی، به جای «اشتباه کردی» بگویید «اینجا ممکنه مشکل ایجاد کنه، راه حل جایگزین فلان است؟». این کار فرهنگ بازخورد سازنده را میسازد.
💡 چطور شروع کنیم؟
- برای هر «Pull Request» حداقل ۱۵ دقیقه وقت بگذارید.
- سوال بپرسید، نه حکم.
- از تیکهای «LGTM» (Looks Good To Me) بیدلیل استفاده نکنید.
📈 نتیجه نهایی:
«Code Review» نه یک تشریفات، بلکه سرمایهگذاری روی کیفیت و یادگیری تیم است. اگر امروز شروع کنید، یک ماه دیگر تفاوت را حس میکنید.
#Codeit #Android #Kotlin #Jetpack #CodeReview #CleanCode #DeveloperGrowth #Teamwork
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🔥2
🎯 Destructuring Declarations در «Kotlin» یکی از اون قابلیتهاییه که کد رو خواناتر و مختصرتر میکنه. بیایید ببینیم چطور کار میکنه و کجا به کار میاد.
🔹 داستراکچرینگ یعنی میتونید یک شیء رو به چند متغیر جداگانه بشکنید بدون اینکه دستی به تک تک فیلدها دسترسی داشته باشید. این کار مخصوصاً با «Data Class»ها عالی جواب میده.
📦 مثال واقعی: فرض کنید یک «User» دارید با فیلدهای name و age. معمولاً مینویسید
🧩 کد مثال رو ببینید:
✅ کد بالا مقدار name و age رو مستقیماً به userName و userAge نسبت میده. نیازی به دسترسی تکی نیست.
🔄 نکته مهم: ترتیب متغیرها با ترتیب فیلدهای constructor یکی هست. اگر فقط بخشی رو میخواید، از
💡 کاربرد عملی: در «Jetpack Compose» برای دریافت «State»های مختلف از «ViewModel» یا در حلقههای روی لیستها خیلی به کار میاد.
📌 نتیجه: داستراکچرینگ باعث میشه کد کمتر و خواناتر داشته باشید. از امروز توی پروژههاتون استفاده کنید.
#Codeit #Android #Kotlin #Jetpack #Destructuring #KotlinTips #CleanCode
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🔹 داستراکچرینگ یعنی میتونید یک شیء رو به چند متغیر جداگانه بشکنید بدون اینکه دستی به تک تک فیلدها دسترسی داشته باشید. این کار مخصوصاً با «Data Class»ها عالی جواب میده.
📦 مثال واقعی: فرض کنید یک «User» دارید با فیلدهای name و age. معمولاً مینویسید
val name = user.name ولی با داستراکچرینگ یک خطی انجامش میدید.🧩 کد مثال رو ببینید:
data class User(val name: String, val age: Int)
fun main() {
val user = User("Ali", 28)
val (userName, userAge) = user
println("$userName is $userAge years old")
}
✅ کد بالا مقدار name و age رو مستقیماً به userName و userAge نسبت میده. نیازی به دسترسی تکی نیست.
🔄 نکته مهم: ترتیب متغیرها با ترتیب فیلدهای constructor یکی هست. اگر فقط بخشی رو میخواید، از
_ استفاده کنید مثلاً val (name, _) = user.💡 کاربرد عملی: در «Jetpack Compose» برای دریافت «State»های مختلف از «ViewModel» یا در حلقههای روی لیستها خیلی به کار میاد.
📌 نتیجه: داستراکچرینگ باعث میشه کد کمتر و خواناتر داشته باشید. از امروز توی پروژههاتون استفاده کنید.
#Codeit #Android #Kotlin #Jetpack #Destructuring #KotlinTips #CleanCode
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
📦 عملگرها در «Kotlin» فقط برای اعداد نیستند!
میتونی به کلاسهای خودت یاد بدی که با علامت
✅ چرا به کار میاد؟
وقتی با مفاهیمی مثل مختصات، ماتریس یا تاریخ کار میکنی، استفاده از عملگرها کد رو خواناتر و طبیعیتر میکنه. دیگه نیازی به نوشتن
💡 مثال عملی:
فرض کن یک کلاس
📝 توضیح:
با کلیدواژه
🎯 کاربرد واقعی:
این قابلیت تو کتابخونههایی مثل «Jetpack Compose» برای مدیریت مقادیر «Dp» یا «Offset» استفاده میشه. مثلاً
🔑 نکته:
میتونی عملگرهای دیگه مثل
#Codeit #Android #Kotlin #Jetpack #OperatorOverloading #CleanCode #Programming
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
میتونی به کلاسهای خودت یاد بدی که با علامت
+ یا == رفتار خاصی داشته باشن. به این میگن «Operator Overloading» 🤯✅ چرا به کار میاد؟
وقتی با مفاهیمی مثل مختصات، ماتریس یا تاریخ کار میکنی، استفاده از عملگرها کد رو خواناتر و طبیعیتر میکنه. دیگه نیازی به نوشتن
point1.add(point2) نیست؛ کافیه بنویسی point1 + point2 ✨💡 مثال عملی:
فرض کن یک کلاس
Point داری که مختصات x و y رو ذخیره میکنه. میخوای دو نقطه رو با + جمع بزنی و نقطه جدیدی بدست بیاری.data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}
fun main() {
val p1 = Point(2, 3)
val p2 = Point(4, 5)
val result = p1 + p2 // فراخوانی plus
println(result) // Point(x=6, y=8)
}
📝 توضیح:
با کلیدواژه
operator به «Kotlin» میفهمونی که تابع plus برای عملگر + استفاده بشه. حالا هر جا p1 + p2 بنویسی، معادل p1.plus(p2) اجرا میشه.🎯 کاربرد واقعی:
این قابلیت تو کتابخونههایی مثل «Jetpack Compose» برای مدیریت مقادیر «Dp» یا «Offset» استفاده میشه. مثلاً
offset1 + offset2 دو مختصات رو جمع میزنه.🔑 نکته:
میتونی عملگرهای دیگه مثل
-، *، []، == و in رو هم overload کنی. فقط کافیه تابع operator مناسب رو بنویسی.#Codeit #Android #Kotlin #Jetpack #OperatorOverloading #CleanCode #Programming
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
🚀 تو کاتلین یه قابلیت باحال به اسم «Infix Functions» داری که میتونه کدت رو روانتر و خواناتر کنه.
بدون اینکه نقطهای قبل از تابع بزاری، مستقیم میتونی صداش کنی. انگار داری با یه عملگر داخلی کار میکنی.
💡 کی به کارت میاد؟
وقتی میخوای یه عملیات ساده رو روی یه شیء انجام بدی و کدت شبیه به جملات طبیعی بشه. مثلاً توی دیتابیس یا DSLهای سفارشی.
📌 چطور تعریفش میکنی؟
فقط کافیه تابع رو با کلمه کلیدی
👇 یه مثال عملی ببین:
✅ اینجا تابع
⚠️ نکات مهم:
- فقط یه پارامتر میگیره.
- پارامتر نباید
- حتماً باید
💡 کجا بیشتر میبینی؟
توی «Kotlin Standard Library» کلی ازش استفاده شده:
📌 تسک نهایی:
برای یه کلاس
خلاصه:
«Infix Functions» یه ابزار ساده ولی قدرتمنده برای خونداییتر کردن کدهات. فقط یادت باشه ازش در جاهای درست استفاده کنی.
#Codeit #Android #Kotlin #InfixFunctions #CleanCode #DSL #ProgrammingTips
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
بدون اینکه نقطهای قبل از تابع بزاری، مستقیم میتونی صداش کنی. انگار داری با یه عملگر داخلی کار میکنی.
💡 کی به کارت میاد؟
وقتی میخوای یه عملیات ساده رو روی یه شیء انجام بدی و کدت شبیه به جملات طبیعی بشه. مثلاً توی دیتابیس یا DSLهای سفارشی.
📌 چطور تعریفش میکنی؟
فقط کافیه تابع رو با کلمه کلیدی
infix مشخص کنی، حتماً یه پارامتر داشته باشه (بدون مقدار پیشفرض) و یه member function یا extension function باشه. 👇 یه مثال عملی ببین:
data class Player(val name: String, val score: Int)
infix fun Player.addScore(points: Int): Player {
return this.copy(score = this.score + points)
}
fun main() {
val player = Player("Ali", 100)
val updatedPlayer = player addScore 50 // بدون نقطه و پرانتز!
println(updatedPlayer) // Player(name=Ali, score=150)
}
✅ اینجا تابع
addScore رو با infix تعریف کردیم. حالا بهجای player.addScore(50) مینویسم player addScore 50. کد روانتر و شبیه به انگلیسی ساده شده. ⚠️ نکات مهم:
- فقط یه پارامتر میگیره.
- پارامتر نباید
vararg باشه. - حتماً باید
member یا extension باشه. 💡 کجا بیشتر میبینی؟
توی «Kotlin Standard Library» کلی ازش استفاده شده:
map, filter, to (مثلاً "key" to "value"). 📌 تسک نهایی:
برای یه کلاس
Matrix یه تابع infix بنویس که دو ماتریس رو جمع بزنه. اینجوری کدت خواناتر و جذابتر میشه. خلاصه:
«Infix Functions» یه ابزار ساده ولی قدرتمنده برای خونداییتر کردن کدهات. فقط یادت باشه ازش در جاهای درست استفاده کنی.
#Codeit #Android #Kotlin #InfixFunctions #CleanCode #DSL #ProgrammingTips
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
🐛 «Bug»ها دشمن نیستند؛ معلمهای بیادعای ما هستند.
🧠 اشکالزدایی فرصتی است برای درک عمیقتر معماری برنامه، منطق کسبوکار و حتی ضعفهای شخصیتان در کدنویسی.
🚀 هر «Bug» یک پازل است؛ حل آن شما را از یک برنامهنویس معمولی به یک توسعهدهنده حرفهای تبدیل میکند.
📌 اولین قدم: «Bug» را شخصی نگیرید. هر «Error» یک پیام خنثی است و قضاوتکننده نیست.
📌 دوم: قبل از جستجوی سریع در Google، خودتان سناریو را بازسازی کنید. «Logcat» را خط به خط بخوانید.
📌 سوم: پس از رفع مشکل، یک یادداشت کوتاه بنویسید: علت ریشهای چه بود؟ چه راهکاری پیدا کردید؟ این کار باعث میشود دیگر همان اشتباه را تکرار نکنید.
💡 مثال واقعی: فرض کنید در یک پروژه اندرویدی «NullPointerException» گرفتید. به جای رفع سریع با «!!»، بررسی کنید چرا متغیر در آن نقطه «null» شده. شاید معماری «ViewModel» نیاز به بازنگری دارد.
🧩 هر «Bug» یک درس طراحی pattern یا اصول SOLID است. اگر آن را نادیده بگیرید، فرصت یادگیری را از دست دادهاید.
🔥 نکته کلیدی: «Debugging» مثل خواندن کتابی است که خودتان نوشتهاید؛ هر اشکال، بخشی از داستان را برایتان روشن میکند.
📈 پس از مدتی، «Bug»ها دیگر ترسناک نیستند؛ نشانههایی برای پیشرفت و تثبیت دانش شما هستند.
#Codeit #Android #Kotlin #Jetpack #Debugging #DeveloperMindset #ProblemSolving #GrowthMindset
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🧠 اشکالزدایی فرصتی است برای درک عمیقتر معماری برنامه، منطق کسبوکار و حتی ضعفهای شخصیتان در کدنویسی.
🚀 هر «Bug» یک پازل است؛ حل آن شما را از یک برنامهنویس معمولی به یک توسعهدهنده حرفهای تبدیل میکند.
📌 اولین قدم: «Bug» را شخصی نگیرید. هر «Error» یک پیام خنثی است و قضاوتکننده نیست.
📌 دوم: قبل از جستجوی سریع در Google، خودتان سناریو را بازسازی کنید. «Logcat» را خط به خط بخوانید.
📌 سوم: پس از رفع مشکل، یک یادداشت کوتاه بنویسید: علت ریشهای چه بود؟ چه راهکاری پیدا کردید؟ این کار باعث میشود دیگر همان اشتباه را تکرار نکنید.
💡 مثال واقعی: فرض کنید در یک پروژه اندرویدی «NullPointerException» گرفتید. به جای رفع سریع با «!!»، بررسی کنید چرا متغیر در آن نقطه «null» شده. شاید معماری «ViewModel» نیاز به بازنگری دارد.
🧩 هر «Bug» یک درس طراحی pattern یا اصول SOLID است. اگر آن را نادیده بگیرید، فرصت یادگیری را از دست دادهاید.
🔥 نکته کلیدی: «Debugging» مثل خواندن کتابی است که خودتان نوشتهاید؛ هر اشکال، بخشی از داستان را برایتان روشن میکند.
📈 پس از مدتی، «Bug»ها دیگر ترسناک نیستند؛ نشانههایی برای پیشرفت و تثبیت دانش شما هستند.
#Codeit #Android #Kotlin #Jetpack #Debugging #DeveloperMindset #ProblemSolving #GrowthMindset
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
📌 آنotationها در «Kotlin» یک ابزار قدرتمند برای افزودن metadata به کد هستند.
🧠 به زبان ساده: annotationها به کامپایلر، runtime یا فریمورکها اطلاعات اضافی میدهند.
🎯 مثل «@Override» در جاوا یا «@Serializable» در «Kotlin Serialization».
🔧 میتوانید annotationهای سفارشی خود را بسازید.
📦 ابتدا یک annotation جدید تعریف میکنیم و با «@Retention» و «@Target» محدوده و زمان نگهداری آن را مشخص میکنیم.
💡 مثال: یک annotation برای فیلدهای JSON بسازیم:
🧩 حالا از آن در یک data class استفاده میکنیم:
🔍 در runtime میتوانیم این annotation را بخوانیم (مثلاً با reflection) تا نام واقعی فیلد در JSON را استخراج کنیم:
✅ این کار باعث میشود کد شما تمیز، قابل توسعه و یکپارچه با کتابخانههای دیگر باشد.
🌟 «Annotations» پایه بسیاری از فریمورکهای اندرویدی مثل «Room»، «Retrofit» و «Dagger» هستند.
#Codeit #Android #Kotlin #Jetpack #Annotations #Reflection #Programming
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🧠 به زبان ساده: annotationها به کامپایلر، runtime یا فریمورکها اطلاعات اضافی میدهند.
🎯 مثل «@Override» در جاوا یا «@Serializable» در «Kotlin Serialization».
🔧 میتوانید annotationهای سفارشی خود را بسازید.
📦 ابتدا یک annotation جدید تعریف میکنیم و با «@Retention» و «@Target» محدوده و زمان نگهداری آن را مشخص میکنیم.
💡 مثال: یک annotation برای فیلدهای JSON بسازیم:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FIELD)
annotation class JsonField(val name: String)
🧩 حالا از آن در یک data class استفاده میکنیم:
data class User(
@JsonField("user_name")
val username: String,
@JsonField("user_age")
val age: Int
)
🔍 در runtime میتوانیم این annotation را بخوانیم (مثلاً با reflection) تا نام واقعی فیلد در JSON را استخراج کنیم:
fun main() {
val field = User::class.java.declaredFields.find { it.name == "username" }
val annotation = field?.getAnnotation(JsonField::class.java)
println(annotation?.name) // خروجی: user_name
}
✅ این کار باعث میشود کد شما تمیز، قابل توسعه و یکپارچه با کتابخانههای دیگر باشد.
🌟 «Annotations» پایه بسیاری از فریمورکهای اندرویدی مثل «Room»، «Retrofit» و «Dagger» هستند.
#Codeit #Android #Kotlin #Jetpack #Annotations #Reflection #Programming
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
📝 قراردادهای کدنویسی کاتلین
کد خواناتر = تیم بهتر = پروژه موفقتر 🚀
«Kotlin» کلی قرارداد رسمی داره که توی «Coding Conventions» اومده.
بیایید ۳ تا از مهمهاش رو با هم مرور کنیم:
✅ نحوه نامگذاری
- کلاسها و آبجکتها: «PascalCase»
- توابع و متغیرها: «camelCase»
- ثابتها: «SCREAMINGSNAKECASE»
✅ ترجیح «val» به «var»
هرجا مقدار تغییر نمیکنه، از «val» استفاده کن. کد ایمانتر و خواناتر میشه.
✅ فاصلهگذاری و «Braces»
آکولاد باز را در انتهای خط بگذار، نه خط جدا.
📌 حالا یه مثال کاربردی از یک کلاس ساده:
این کد از قراردادهای نامگذاری پیروی میکنه، از «val» بهجای «var» استفاده کرده و «Braces» رو درست گذاشته.
🔥 نتیجه: رعایت این قراردادها باعث میشه کدت مثل آب روان باشه و توی پروژههای تیمی هیچکس سردرگم نشه.
#Codeit #Android #Kotlin #Jetpack #CodingConventions #CleanCode
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
کد خواناتر = تیم بهتر = پروژه موفقتر 🚀
«Kotlin» کلی قرارداد رسمی داره که توی «Coding Conventions» اومده.
بیایید ۳ تا از مهمهاش رو با هم مرور کنیم:
✅ نحوه نامگذاری
- کلاسها و آبجکتها: «PascalCase»
- توابع و متغیرها: «camelCase»
- ثابتها: «SCREAMINGSNAKECASE»
✅ ترجیح «val» به «var»
هرجا مقدار تغییر نمیکنه، از «val» استفاده کن. کد ایمانتر و خواناتر میشه.
✅ فاصلهگذاری و «Braces»
آکولاد باز را در انتهای خط بگذار، نه خط جدا.
📌 حالا یه مثال کاربردی از یک کلاس ساده:
class User(private val name: String, private val age: Int) {
fun isAdult(): Boolean = age >= 18
fun greeting(): String {
return "Hello, my name is $name"
}
}
این کد از قراردادهای نامگذاری پیروی میکنه، از «val» بهجای «var» استفاده کرده و «Braces» رو درست گذاشته.
🔥 نتیجه: رعایت این قراردادها باعث میشه کدت مثل آب روان باشه و توی پروژههای تیمی هیچکس سردرگم نشه.
#Codeit #Android #Kotlin #Jetpack #CodingConventions #CleanCode
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🔥2
سلام! 🚀
«Inline Functions» یکی از قدرتمندترین ابزارهای بهینهسازی در «Kotlin» هستند که خیلی از توسعهدهندگان پیشرفته ازش استفاده میکنند، اما کمتر کسی واقعاً عمقش رو درک میکنه. بیا ببینیم چطور کار میکنه و چه فایدهای داره. 😎
وقتی یک «Higher-Order Function» مینویسید که «lambda» میگیره، هر بار که صدا زده بشه، یک «anonymous class» ساخته میشه که حافظه و پردازنده رو هدر میده. اینجاست که «inline» به کمک میاد: بدنه تابع رو مستقیم در محل فراخوانی کپی میکنه و overhead رو حذف میکنه. 🔥
مثال واقعی: فرض کنید تابعی داریم که عملیات سنگینی رو روی یک لیست انجام میده و میخوایم callback بگیریم. با «inline» این عملیات سریعتر و کممصرفتر اجرا میشه.
کد زیر رو ببین:
این کد چیکار میکنه؟ علامت «inline» جلوی تابع باعث میشه کامپایلر بدنه تابع رو بهجای صدا زدن، در محل فراخوانی قرار بده. نتیجه: هیچ شیء ناشناسی ساخته نمیشه و سرعت اجرا افزایش پیدا میکنه. همچنین از «crossinline» برای اجازه استفاده از «non-local return» در داخل «lambda» استفاده کردیم. 🧠
نکته مهم: «inline» رو فقط برای «Higher-Order Functions» که «lambda» میگیرن و اندازه کوچیکی دارن به کار ببرید. استفاده بیجا میتونه حجم کد رو زیاد کنه. 🎯
حالا برو کدهای خودت رو بررسی کن و ببین کجا میتونی با «inline» کارآیی رو افزایش بدی! 💪
#Codeit #Android #Kotlin #Jetpack #InlineFunctions #KotlinPerformance
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
«Inline Functions» یکی از قدرتمندترین ابزارهای بهینهسازی در «Kotlin» هستند که خیلی از توسعهدهندگان پیشرفته ازش استفاده میکنند، اما کمتر کسی واقعاً عمقش رو درک میکنه. بیا ببینیم چطور کار میکنه و چه فایدهای داره. 😎
وقتی یک «Higher-Order Function» مینویسید که «lambda» میگیره، هر بار که صدا زده بشه، یک «anonymous class» ساخته میشه که حافظه و پردازنده رو هدر میده. اینجاست که «inline» به کمک میاد: بدنه تابع رو مستقیم در محل فراخوانی کپی میکنه و overhead رو حذف میکنه. 🔥
مثال واقعی: فرض کنید تابعی داریم که عملیات سنگینی رو روی یک لیست انجام میده و میخوایم callback بگیریم. با «inline» این عملیات سریعتر و کممصرفتر اجرا میشه.
کد زیر رو ببین:
inline fun processItems(
items: List<Int>,
crossinline operation: (Int) -> Unit
) {
for (item in items) {
operation(item)
}
}
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
processItems(numbers) { number ->
println("Processing: $number")
}
}
این کد چیکار میکنه؟ علامت «inline» جلوی تابع باعث میشه کامپایلر بدنه تابع رو بهجای صدا زدن، در محل فراخوانی قرار بده. نتیجه: هیچ شیء ناشناسی ساخته نمیشه و سرعت اجرا افزایش پیدا میکنه. همچنین از «crossinline» برای اجازه استفاده از «non-local return» در داخل «lambda» استفاده کردیم. 🧠
نکته مهم: «inline» رو فقط برای «Higher-Order Functions» که «lambda» میگیرن و اندازه کوچیکی دارن به کار ببرید. استفاده بیجا میتونه حجم کد رو زیاد کنه. 🎯
حالا برو کدهای خودت رو بررسی کن و ببین کجا میتونی با «inline» کارآیی رو افزایش بدی! 💪
#Codeit #Android #Kotlin #Jetpack #InlineFunctions #KotlinPerformance
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🔥1
🔴 تو از زندگی عقب نیستی، تو دقیقا تو زمان درست خودت هستی!
@CodeitMobile
رسیدن به یه بدن زیبا، حدودا ۵ سال زمان میخواد نه ۶ ماه!
میانگین سن یه میلیونر ۵۷ ساله، نه ۲۰ سال.
بیشتر آدما بعد از ۲۷ سالگی شریک زندگیشون رو پیدا میکنن، نه تو ۱۸ سالگی!
یه کسب و کار موفق، بین ۷ تا ۱۰ سال زمان میبره، نه ۱ سال.
میانگین سن خرید خونه ۳۸ سالگیه، نه ۲۳ سال.
@CodeitMobile
❤2🔥1
🔄 کی کد رو ریفکتور کنیم؟
رفکتورینگ مثل مرتبکردن کمد لباس میمونه؛ اگه مرتب نکنی، پیدا کردن یه تیشرت ساده هم ساعتها طول میکشه.
تو پروژههای اندروید با «Kotlin» و «Jetpack Compose» کدها سریع پیچیده میشن.
اما هر تغییر کوچیکی رو نباید ریفکتور کرد. باید بدونیم کی واقعاً لازمه.
📌 نشونههایی که وقت ریفکتور رسیده:
1️⃣ بوی بد کد: متدهای بلند، نامهای نامفهوم، یا تکرار یک «ViewModel» مشابه در چند کلاس.
2️⃣ تستنشدن: وقتی اضافه کردن یه فیچر ساده، تست قبلی رو میشکونه، یعنی ساختار کد نیاز به بازبینی داره.
3️⃣ یادگیری تیم: اگر اعضای جدید مدام سردرگم میشن، پس معماری شفاف نیست.
4️⃣ تغییر تکنولوژی: مثلاً از «LiveData» به «StateFlow» کوچ میکنید – عالی، ولی بدون ریفکتور ممکنه کد دوگانه بشه.
✅ چه وقت ریفکتور نکنیم؟
- وقتی ددلاین نزدیکه و ریسک خرابی بالاست.
- وقتی کد کار میکنه و هیچ باگی نداره (اصل «If it ain't broke, don't fix it»).
- وقتی تیم در میانه یه فیچر بزرگ هست.
🛠 یک قانون عملی:
در هر اسپرینت ۲۰٪ وقت رو به «ریفکتور» اختصاص بدین.
مثلاً توی «Jetpack Compose» اگر دیدید یه composable بیش از ۸۰ خط شده، بیخیال نشید.
یک تابع «extract» بزنید و بخشهای تکراری رو به composableهای جدا تبدیل کنید.
💡 نتیجه:
رفکتورینگ هوشمندانه باعث میشه سرعت توسعه آینده چند برابر بشه.
از کدی که گربهشو ازش خبر نداره فرار کنید 🐈
#Codeit #Android #Kotlin #Jetpack #Refactoring #CleanCode #MobileDev #SoftwareEngineering
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
رفکتورینگ مثل مرتبکردن کمد لباس میمونه؛ اگه مرتب نکنی، پیدا کردن یه تیشرت ساده هم ساعتها طول میکشه.
تو پروژههای اندروید با «Kotlin» و «Jetpack Compose» کدها سریع پیچیده میشن.
اما هر تغییر کوچیکی رو نباید ریفکتور کرد. باید بدونیم کی واقعاً لازمه.
📌 نشونههایی که وقت ریفکتور رسیده:
1️⃣ بوی بد کد: متدهای بلند، نامهای نامفهوم، یا تکرار یک «ViewModel» مشابه در چند کلاس.
2️⃣ تستنشدن: وقتی اضافه کردن یه فیچر ساده، تست قبلی رو میشکونه، یعنی ساختار کد نیاز به بازبینی داره.
3️⃣ یادگیری تیم: اگر اعضای جدید مدام سردرگم میشن، پس معماری شفاف نیست.
4️⃣ تغییر تکنولوژی: مثلاً از «LiveData» به «StateFlow» کوچ میکنید – عالی، ولی بدون ریفکتور ممکنه کد دوگانه بشه.
✅ چه وقت ریفکتور نکنیم؟
- وقتی ددلاین نزدیکه و ریسک خرابی بالاست.
- وقتی کد کار میکنه و هیچ باگی نداره (اصل «If it ain't broke, don't fix it»).
- وقتی تیم در میانه یه فیچر بزرگ هست.
🛠 یک قانون عملی:
در هر اسپرینت ۲۰٪ وقت رو به «ریفکتور» اختصاص بدین.
مثلاً توی «Jetpack Compose» اگر دیدید یه composable بیش از ۸۰ خط شده، بیخیال نشید.
یک تابع «extract» بزنید و بخشهای تکراری رو به composableهای جدا تبدیل کنید.
💡 نتیجه:
رفکتورینگ هوشمندانه باعث میشه سرعت توسعه آینده چند برابر بشه.
از کدی که گربهشو ازش خبر نداره فرار کنید 🐈
#Codeit #Android #Kotlin #Jetpack #Refactoring #CleanCode #MobileDev #SoftwareEngineering
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🔥1🥰1
🥶 تا حالا شده توی «Kotlin» بخوای تایپ یه پارامتر جنریک رو توی «inline function» چک کنی، اما «JVM» به خاطر «type erasure» اجازه نده؟ «Reified type parameters» دقیقاً همین مشکل رو حل میکنه!
🔍 توی «Kotlin» معمولاً تایپ پارامترهای جنریک موقع اجرا پاک میشن (type erasure). اما با ترکیب کلمه کلیدی «reified» و «inline function» میتونی تایپ رو موقع اجرا نگه داری و مثلاً ازش توی «instanceof» استفاده کنی.
📌 کاربرد عملی: فرض کن یه تابع میخوای که لیستی از اشیا میگیره و فقط اونایی که از یه تایپ خاص هستن رو برمیگردونه. بدون «reified» باید «Class» رو به عنوان آرگومان پاس بدی، اما با «reified» خیلی تمیزتر میشه.
کد زیر یه مثال ساده از فیلتر کردن لیست با تایپ رریفاید:
🧠 این کد چیکار میکنه؟ تابع «filterByType» با «reified T» تعریف شده، بنابراین داخل بدنه میتونیم از «is T» استفاده کنیم. «JVM» موقع اجرا تایپ رو میدونه و خطای «ClassCastException» نمیخوری.
💡 نکته مهم: «reified» فقط توی «inline function» کار میکنه. پس حواست باشه تابع رو با «inline» علامتگذاری کنی.
✅ حالا میتونی توی پروژههات از «Reified type parameters» برای سادهسازی کدهای تکراری و حذف «Class» آرگومانها استفاده کنی.
#Codeit #Android #Kotlin #Jetpack #Generics #TypeSafety #KotlinTips
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🔍 توی «Kotlin» معمولاً تایپ پارامترهای جنریک موقع اجرا پاک میشن (type erasure). اما با ترکیب کلمه کلیدی «reified» و «inline function» میتونی تایپ رو موقع اجرا نگه داری و مثلاً ازش توی «instanceof» استفاده کنی.
📌 کاربرد عملی: فرض کن یه تابع میخوای که لیستی از اشیا میگیره و فقط اونایی که از یه تایپ خاص هستن رو برمیگردونه. بدون «reified» باید «Class» رو به عنوان آرگومان پاس بدی، اما با «reified» خیلی تمیزتر میشه.
کد زیر یه مثال ساده از فیلتر کردن لیست با تایپ رریفاید:
inline fun <reified T> List<*>.filterByType(): List<T> {
return this.filter { it is T }.map { it as T }
}
fun main() {
val mixed = listOf("Hello", 42, "World", 3.14)
val strings: List<String> = mixed.filterByType<String>()
println(strings) // [Hello, World]
}
🧠 این کد چیکار میکنه؟ تابع «filterByType» با «reified T» تعریف شده، بنابراین داخل بدنه میتونیم از «is T» استفاده کنیم. «JVM» موقع اجرا تایپ رو میدونه و خطای «ClassCastException» نمیخوری.
💡 نکته مهم: «reified» فقط توی «inline function» کار میکنه. پس حواست باشه تابع رو با «inline» علامتگذاری کنی.
✅ حالا میتونی توی پروژههات از «Reified type parameters» برای سادهسازی کدهای تکراری و حذف «Class» آرگومانها استفاده کنی.
#Codeit #Android #Kotlin #Jetpack #Generics #TypeSafety #KotlinTips
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤1🔥1
🔹 الگوی «Delegation» در «Kotlin» یکی از قدرتمندترین ابزارهای طراحی است که به شما اجازه میدهه بدون ارثبری مستقیم، قابلیتهای یک کلاس رو به کلاس دیگه واگذار کنی!
🔹 «Delegation» یعنی به جای اینکه کلاس A همه متدهای کلاس B رو پیادهسازی کنه، اونها رو به یک شیء از کلاس B بسپاره.
🔹 «Kotlin» با کلیدواژه «by» این کار رو خیلی راحت کرده. کافیه توی تعریف کلاس از «by» استفاده کنی تا پیادهسازی متدها به طور خودکار از شیء delegat گرفته بشه.
🔹 مزیت اصلی: کاهش وابستگی به «Inheritance» و افزایش ترکیبپذیری کد. دیگه لازم نیست با سلسلهمراتب پیچیده ارثبری کلنجار بری.
🔹 کاربرد واقعی: مثلاً فرض کن یک «Interface» به نام «Logger» داری که متد «log» رو تعریف میکنه. میتونی دو پیادهسازی مختلف براش بنویسی: یکی برای چاپ در کنسول و یکی برای ذخیره در فایل. بعد با «Delegation» کلاس اصلی رو به یکی از این پیادهسازیها وصل کنی.
🔹 کد زیر رو ببین:
🔹 اینجا «UserService» واسط «Logger» رو از طریق شیء ورودی (مثلاً «ConsoleLogger») پیادهسازی میکنه. هر وقت توی «UserService» متد «log» صدا زده بشه، به طور خودکار به «ConsoleLogger» برونسپاری میشه.
🔹 با این روش میتونی رفتار «UserService» رو بدون تغییر کد اصلی، عوض کنی. مثلاً یه «FileLogger» بدی بهش تا لاگها توی فایل ذخیره بشه.
🔹 نکته: «Delegation» مخصوصاً در الگوهای طراحی مثل «Strategy»، «Decorator» و حتی «Dependency Injection» کاربردی داره. یادش بگیر تا کدت خیلی تمیزتر و تستپذیرتر بشه.
🔹 برای پیشرفتهترها: ترکیب «Delegation» با «Property Delegates» تو «Kotlin» (مثل «lazy»، «observable») یه دنیا امکانات در اختیارت میذاره.
#Codeit #Android #Kotlin #Jetpack #DelegationPattern #CleanCode #SoftwareDesign #OOP
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
🔹 «Delegation» یعنی به جای اینکه کلاس A همه متدهای کلاس B رو پیادهسازی کنه، اونها رو به یک شیء از کلاس B بسپاره.
🔹 «Kotlin» با کلیدواژه «by» این کار رو خیلی راحت کرده. کافیه توی تعریف کلاس از «by» استفاده کنی تا پیادهسازی متدها به طور خودکار از شیء delegat گرفته بشه.
🔹 مزیت اصلی: کاهش وابستگی به «Inheritance» و افزایش ترکیبپذیری کد. دیگه لازم نیست با سلسلهمراتب پیچیده ارثبری کلنجار بری.
🔹 کاربرد واقعی: مثلاً فرض کن یک «Interface» به نام «Logger» داری که متد «log» رو تعریف میکنه. میتونی دو پیادهسازی مختلف براش بنویسی: یکی برای چاپ در کنسول و یکی برای ذخیره در فایل. بعد با «Delegation» کلاس اصلی رو به یکی از این پیادهسازیها وصل کنی.
🔹 کد زیر رو ببین:
interface Logger {
fun log(message: String)
}
class ConsoleLogger : Logger {
override fun log(message: String) {
println("Console: $message")
}
}
class FileLogger : Logger {
override fun log(message: String) {
// ذخیره در فایل
}
}
class UserService(logger: Logger) : Logger by logger {
fun createUser(name: String) {
log("Creating user $name")
// منطق ساخت کاربر
}
}
🔹 اینجا «UserService» واسط «Logger» رو از طریق شیء ورودی (مثلاً «ConsoleLogger») پیادهسازی میکنه. هر وقت توی «UserService» متد «log» صدا زده بشه، به طور خودکار به «ConsoleLogger» برونسپاری میشه.
🔹 با این روش میتونی رفتار «UserService» رو بدون تغییر کد اصلی، عوض کنی. مثلاً یه «FileLogger» بدی بهش تا لاگها توی فایل ذخیره بشه.
🔹 نکته: «Delegation» مخصوصاً در الگوهای طراحی مثل «Strategy»، «Decorator» و حتی «Dependency Injection» کاربردی داره. یادش بگیر تا کدت خیلی تمیزتر و تستپذیرتر بشه.
🔹 برای پیشرفتهترها: ترکیب «Delegation» با «Property Delegates» تو «Kotlin» (مثل «lazy»، «observable») یه دنیا امکانات در اختیارت میذاره.
#Codeit #Android #Kotlin #Jetpack #DelegationPattern #CleanCode #SoftwareDesign #OOP
🌐 Codeit → https://code-it.ir
━━━━━━━━━━━━━━━
@CodeitMobile
❤2