Codeit Mobile
94 subscribers
3 photos
1 video
243 links
📱 آموزش برنامه‌نویسی موبایل

Kotlin • Android

🚀 آموزش ساده، کاربردی و پروژه‌محور
💡 مخصوص توسعه‌دهندگان موبایل
Download Telegram
🔵 آبجکت‌ها در کاتلین؛ فراتر از کلاس‌های معمولی!

۱️⃣ object یعنی تعریف یک singleton بدون دردسر 🧩
۲️⃣ companion object جایگزین اعضای static در جاوا 🚀
۳️⃣ object expression ساخت anonymous object در لحظه 🎯
۴️⃣ داخل companion می‌تونی از const val برای ثابت‌ها استفاده کنی 🧮
۵️⃣ با object دیگه نیازی به الگوی Singleton نخواهی داشت 🙌
۶️⃣ همچنین میشه از آبجکت‌ها به عنوان delegate برای delegation استفاده کرد 🧠
۷️⃣ نکته: companion object می‌تونه نام داشته باشه یا anonymous باشه 📌

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1
اشیاء در کاتلین فراتر از اشیاء ساده هستند! 🎯
🔹 object برای تعریف singleton بدون نیاز به کلاس اضافی
🔹 companion object برای اعضای استاتیک مثل جاوا، اما خواناتر
🔹 object expression برای ایجاد anonymous object درجا
🔹 همه اینها در سطح باینری بهینه و thread-safe هستند
🔹 مثال: object NetworkConfig { ... } یک نمونه سراسری
🔹 نکته: companion object در واقع یک شیء تو در توست، نه static واقعی
🔹 اشیاء می‌توانند از کلاس‌ها و اینترفیس‌ها ارث برند
⚡️ با این ابزارها کد تمیزتر و بدون boilerplate می‌نویسید
📚 این مبحث پایه‌ای برای الگوهای طراحی در کاتلینه
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1
🔷 مفهوم ارث‌بری (Inheritance) در Kotlin – سطح متوسط 🧬

ارث‌بری یکی از مفاهیم اصلی شیء‌گراییه که به شما اجازه میده کلاس‌های جدیدی بر پایه کلاس‌های موجود بسازید.
در Kotlin، کلاس‌ها به‌طور پیش‌فرض final هستند و برای ارث‌بری باید با کلیدواژه open مشخص بشن.

مثال عملی: فرض کنید یک کلاس پایه Animal داریم:

open class Animal(val name: String) {
open fun sound() = "Some sound"
}


حالا یک کلاس Cat از آن ارث می‌بریم:

class Cat(name: String) : Animal(name) {
override fun sound() = "Meow"
}


در اینجا open اجازه override متد sound رو میده.
سازنده کلاس والد با : Animal(name) صدا زده میشه.

🔸 نکات مهم:
- برای override حتماً از override استفاده کنید.
- اگر کلاس والد سازنده بدون پارامتر نداره، باید پارامترها رو پاس بدید.
- ارث‌بری چندگانه نداریم (ترجیحاً از interface استفاده کنید).

🔹 مثال پیشرفته‌تر: استفاده از super برای دسترسی به متد والد:

open class Dog(name: String) : Animal(name) {
final override fun sound() = "Woof" // متد نهایی
}


این کد نشون میده که با final می‌شه از override مجدد جلوگیری کرد.

📌 ارث‌بری رو در پروژه‌های واقعی برای باز استفاده از کد و اعمال چندریختی (Polymorphism) به کار ببرید.

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
📌 اینترفیس‌های Kotlin رو جدی بگیر؛ اگه فقط با کلاس‌های abstract کار کردی، نصف راه رو رفتی!

اینترفیس‌ها قراردادهای قدرتمندی هستن که بدون وابستگی به سلسله‌مراتب، رفتار رو تعریف می‌کنن.
💡 توی یک اپ واقعی، مثلاً می‌خوای انواع مختلف پرداخت (کارت، کیف پول، رمزارز) رو مدیریت کنی.

📌 هر سرویس پرداخت باید متد pay(amount) رو داشته باشه. با اینترفیس یه قرارداد می‌بندی و پیاده‌سازی رو به کلاس‌ها می‌سپاری.

👇 نمونه کد ساده اما کاربردی:

interface PaymentService {
fun pay(amount: Double): String
fun validate(): Boolean
}

class CardPayment : PaymentService {
override fun pay(amount: Double): String {
return "پرداخت $amount با کارت انجام شد."
}
override fun validate(): Boolean {
// اعتبارسنجی شماره کارت
return true
}
}

class WalletPayment : PaymentService {
override fun pay(amount: Double): String {
return "پرداخت $amount از کیف پول انجام شد."
}
override fun validate(): Boolean {
// بررسی موجودی
return true
}
}


اینترفیس بهت انعطاف می‌ده: می‌تونی هر کلاس جدیدی بدون تغییر کد قبلی اضافه کنی.
💡 بهترین تمرین: برای هر «قابلیت» در اپت یه اینترفیس در نظر بگیر، بعد dependency injection رو استفاده کن.

#Kotlin #Interface #AndroidDev #CleanArchitecture #Codeit #کدایت #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
📦 Data Class در کاتلین چیزی فراتر از یک کلاس ساده است!
وقتی از data class استفاده می‌کنی، کاتلین خودش متدهای toString، equals، hashCode، copy و componentN رو می‌سازه.

🧩 مشکل: تو پروژه‌های بزرگ مجبوری بارها کد تکراری برای مدل‌ها بنویسی.
راه‌حل: data class با یه خط کد تمام این کارها رو برات انجام میده.

🔄 یک مثال واقعی: مدل کاربر با فیلدهای nullable و نیاز به کپی کردن یه مقدار تغییر یافته.

🧪 کد عملی:
data class User(
val id: Int,
val name: String,
val email: String?,
val isActive: Boolean = true
)

fun main() {
val original = User(1, "Ali", "ali@example.com", true)
val updated = original.copy(email = null, isActive = false)
println(original) // User(id=1, name=Ali, email=ali@example.com, isActive=true)
println(updated) // User(id=1, name=Ali, email=null, isActive=false)

// Destructuring
val (id, name, email) = updated
println("$id - $name - $email") // 1 - Ali - null
}


📋 توضیح:
- copy() بدون تغییر فیلدهای دیگه، یه نمونه جدید با فیلدهای دلخواه می‌سازه.
- Destructuring به کمک componentN کار میکنه و کد خوندنی‌تری میده.

🚀 نکته حرفه‌ای:
از data class فقط برای نگهداری داده استفاده کن (نه منطق سنگین).
برای حفظ immutability فیلدها رو با val تعریف کن.

#DataClass #KotlinTips #CleanCode #Destructuring #Model #Codeit #کدایت #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
🔹 تا حالا خواستی یه مجموعه ثابت از مقادیر رو توی کاتلین مدیریت کنی؟
🔸 Enum Class دقیقاً برای همینه! یه نوع خاص از کلاس که مقادیر از پیش تعریف‌شده داره و می‌تونه رفتار اختصاصی هم داشته باشه.

🔹 فرض کن قراره وضعیت‌های یه سفارش رو مدل کنی: Pending, Shipped, Delivered.
🔸 بدون Enum مجبوری از String یا Int استفاده کنی و خطاهای انسانی زیاد میشه. اما Enum کلاس اون رو تایپ-سیف و خواناتر می‌کنه.

🔹 Enum توی کاتلین خیلی فراتر از یه لیست ساده‌ست:
🔸 می‌تونه پراپرتی داشته باشه، متد داشته باشه، حتی اینترفیس implement کنه.

🔹 مثال عملی: یه ماشین‌حالت ساده برای پردازش سفارش با انتقال بین وضعیت‌ها:

enum class OrderStatus(val label: String) {
Pending("در انتظار تأیید"),
Shipped("ارسال شده"),
Delivered("تحویل داده شده"),
Cancelled("لغو شده");

fun canTransitionTo(next: OrderStatus): Boolean {
return when (this) {
Pending -> next == Shipped || next == Cancelled
Shipped -> next == Delivered
else -> false
}
}
}

fun main() {
val current = OrderStatus.Pending
println(current.label) // در انتظار تأیید
println(current.canTransitionTo(OrderStatus.Shipped)) // true
}


🔹 این کد نشون میده که هر وضعیت یه label (برچسب فارسی) داره و منطق انتقال مجاز بین وضعیت‌ها رو توی متد canTransitionTo تعریف کردیم.
🔸 مزیت: خطای انسانی کم میشه، کد خوانا و قابل نگهداری‌ست.

🔹 یه نکته حرفه‌ای: از Enum برای ثابت‌هایی که رفتار متفاوت دارن استفاده کن (مثل Strategy Pattern ساده).
🔸 از when به جای if-های طولانی استفاده کن تا کد تمیز بمونه.

#EnumClass #Kotlin #کاتلین #برنامه‌نویسی #Android #Codeit #کدایت #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1
🧩 آیا تا به حال شده که بخوای یه وضعیت خاص رو توی کدهات مدیریت کنی ولی enum جواب نده؟
بیا با Sealed Class آشنا بشیم؛ یه ابزار قدرتمند توی Kotlin برای تعریف محدودیت‌های دقیق روی نوع‌ها.

📦 Sealed Class چیه؟
یه کلاس که زیرکلاس‌هاش فقط توی همون فایل یا package تعریف میشن. این یعنی کامپایلر همه‌ی حالت‌های ممکن رو می‌دونه و می‌تونه exhaustive بودن when رو تضمین کنه.

کاربرد واقعی: مدیریت stateهای مختلف یه صفحه (Loading, Success, Error).
به‌جای if/else بی‌نظم، از sealed class استفاده کن تا کدت خواناتر و مطمئن‌تر بشه.

🔧 بیایید یه مثال ساده ببینیم:

sealed class UiState {
object Loading : UiState()
data class Success(val data: String) : UiState()
data class Error(val message: String) : UiState()
}

fun handleState(state: UiState) {
when (state) {
is UiState.Loading -> println("در حال بارگذاری... 🌀")
is UiState.Success -> println("داده دریافت شد: ${state.data} ")
is UiState.Error -> println("خطا: ${state.message} ")
}
}


💡 این کد چیکار میکنه؟
سه حالت ممکن رو با sealed class تعریف کردیم. when exhaustive هست و نیازی به else نداره. اگه بعداً یه حالت جدید اضافه کنی، کامپایلر اخطار میده که باید مدیریتش کنی.

🚀 نکته‌ی کاربردی:
از sealed class برای Representation‌های محدود (مثلا نوع خطاها، نتیجه‌ی API، یا ناوبری صفحه‌ها) استفاده کن. این کار type safety رو افزایش میده و کدت رو پیش‌بینی‌پذیرتر میکنه.

#SealedClass #Kotlin #Android #Jetpack #کدایت #Codeit #AndroidDev
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
توابع الحاقی (Extension Functions) تو کاتلین، یه قابلیت جادویی‌ان که بهت اجازه میدن بدون ارث‌بری یا تغییر کلاس، متد جدید بهش اضافه کنی! 🪄

🧠 فرض کن یه کلاس از کتابخونه‌ی شخص ثالث داری و میخوای یه متد خاص روش پیاده‌سازی کنی. با Extension Functions میتونی انگار که اون متد جزو کلاس اصلیه، ازش استفاده کنی.

📱 مثال واقعی: فرض کن میخوای یه String رو به صورت URL-safe encode کنی، ولی متد آماده نداره. میتونی یه Extension Function بنویسی:

fun String.toUrlSafe(): String {
return this.replace(" ", "%20")
.replace("?", "%3F")
.replace("&", "%26")
}

// استفاده
val unsafe = "hello world?query=test&item=1"
val safe = unsafe.toUrlSafe()
println(safe) // hello%20world%3Fquery%3Dtest%26item%3D1


این کد یه متد جدید به اسم toUrlSafe به String اضافه میکنه. درون خودش با this به رشته‌ی اصلی دسترسی داری و جای کاراکترهای خاص رو با کدهای URL می‌ذاره.

🎯 نکته: Extension Functions静态 (static) هستن و override نمی‌شن. اگر کلاس همون متد رو داشته باشه، اولویت با متد اصلیه.

🔥 بهترین تمرین: از Extension Functions برای جدا کردن منطق کمکی از کلاس‌های اصلی استفاده کن، مخصوصاً برای Utility functions.

#ExtensionFunctions #KotlinTips #Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
🔍 توابع scope در Kotlin ابزاری قدرتمند برای مدیریت context اشیاء هستن، اما استفاده نادرست ازشون کد رو پیچیده می‌کنه. بیا با مثال ساده یاد بگیریم! 🚀

توابع scope (let, run, with, apply, also) بهت اجازه می‌دن عملیات روی یک شیء رو داخل یه بلاک محدود انجام بدی. فرق اصلیشون در نتیجه برگشتی و نحوه دسترسی به شیء هست (با it یا this). 🧩

مثال واقعی: فرض کن یه User داری و می‌خوای مقادیرش رو ببینی، تغییر بدی و بعد validation کنی. با apply و let می‌تونی خیلی خواناتر بنویسی.

📌 کد مثال:
data class User(var name: String, var email: String)

fun main() {
val user = User("", "")

user.apply {
name = "Sara"
email = "sara@example.com"
}.let {
println("User created: ${it.name}, ${it.email}")
// validation
if (it.email.contains("@")) it else null
}?.run {
println("Valid user: $name")
} ?: println("Invalid email")
}


توضیح کد:
- apply مقادیر رو تنظیم می‌کنه و خود شیء رو برمی‌گردونه.
- let با it به شیء دسترسی داره و نتیجه آخر رو برمی‌گردونه (اینجا null یا خود شیء).
- run روی شیء غیر null اجرا میشه و با this کار می‌کنه.

نکته کاربردی:
برای زنجیره‌سازی عملیات بدون متغیرهای موقت، از apply برای تنظیم و let برای پردازش استفاده کن. از also برای side-effects (مثل لاگ) استفاده کن.

🏷️ #Scope #Kotlin #ScopeFunctions #کاتلین #JVM #AndroidDev
#Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
📌 می‌دونی چرا کلکسیون‌های Kotlin محبوب‌ترین ابزار هر دولوپر اندروید هستن؟ 🚀

📚 تو دنیای واقعی، داده‌ها به صورت لیست، ست یا مپ ذخیره می‌شن. Kotlin با extension function‌های قدرتمندش مثل map و filter کار رو خیلی راحت کرده. فرض کن یه لیست از یوزرها داری و می‌خوای فقط اسم اون‌هایی که سنشون بالای ۱۸ هست رو نشون بدی. 🎯

🛠️ بیا با یه مثال عملی ببینیم چطور میشه از filter و map استفاده کرد:

data class User(val name: String, val age: Int)

val users = listOf(
User("Ali", 22),
User("Sara", 17),
User("Reza", 30)
)

val adultNames = users
.filter { it.age >= 18 }
.map { it.name }

println(adultNames) // [Ali, Reza]


کد بالا اول کاربران بالای ۱۸ رو فیلتر می‌کنه و بعد فقط اسمشون رو استخراج می‌کنه. این ترکیب از کلکسیون‌ها باعث میشه کدت خواناتر و دیباگش راحت‌تر باشه.

💡 نکته حرفه‌ای: همیشه از sequence برای داده‌های بزرگ استفاده کن تا عملکرد بهتری داشته باشی. asSequence() رو یادت نره!

#Kotlin #Collections #Filter #Map #Sequence #Codeit #کدایت #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🚀 تابع‌های بی‌نام (Lambda) توی کاتلین مثل یه ابزار جادویی‌ان که باعث می‌شن کدت خواناتر و کوتاه‌تر بشه.
📌 لامبدا یه بلاک کد هست که می‌تونی به‌عنوان آرگومان به توابع دیگه بدی.

💡 مثلاً توی لیست‌ها، به‌جای نوشتن حلقه‌ی کامل، از filter و map با لامبدا استفاده می‌کنی:

val numbers = listOf(1, 2, 3, 4, 5, 6)
val evenNumbers = numbers.filter { it % 2 == 0 }
println(evenNumbers) // خروجی: [2, 4, 6]


🧠 اینجا it همون عنصر جاری لیست هست. لامبدا رو با {} تعریف می‌کنیم و آخرین عبارت داخلش مقدار برگشتی محسوب می‌شه.

⚙️ یه مثال عملی: توی پروژه‌های Jetpack Compose خیلی از لامبدا استفاده می‌کنی:

Button(onClick = { 
// کاری که باید با کلیک انجام بشه
println("دکمه کلیک شد!")
}) {
Text("کلیک کن")
}


لامبداها کدتو جمع‌وجور می‌کنن و وابستگی به کلاس‌های مجزا رو کم می‌کنن.
📝 نکته: از لامبدا فقط برای عملیات کوتاه استفاده کن؛ برای منطق پیچیده‌تر تابع جدا بنویس.

#Lambda #Kotlin #FunctionalProgramming
#Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🎯 تابع‌های مرتبه بالا (Higher-Order Functions) رو قورت بده!
دیگه نیازی نیست کلی حلقه تکراری بنویسی. 🚀

🌀 تابع مرتبه بالا یعنی تابعی که ورودیش یک تابع دیگه‌ست یا خروجیش یک تابع برمی‌گردونه.
مثلاً می‌تونی باهاش منطق رو از تابع اصلی جدا کنی و کد رو خواناتر و ماژولارتر بنویسی.

کاربرد واقعی:
فرض کن داری یه پردازش روی لیست محصولات انجام میدی. گاهی نیاز داری فیلتر کنی، گاهی مرتب کنی، گاهی نقشه (map) بکشی.
به جای نوشتن تابع جدا برای هر کدوم، یه تابع مرتبه بالا می‌نویسی که منطق رو به عنوان پارامتر دریافت کنه.

🔧 مثال عملی با Kotlin:

data class Product(val name: String, val price: Int)

fun List<Product>.customFilter(predicate: (Product) -> Boolean): List<Product> {
val result = mutableListOf<Product>()
for (item in this) {
if (predicate(item)) {
result.add(item)
}
}
return result
}

// استفاده
val products = listOf(
Product("Laptop", 1500),
Product("Mouse", 25),
Product("Keyboard", 80)
)

val expensiveProducts = products.customFilter { it.price > 100 }
println(expensiveProducts) // [Product(name=Laptop, price=1500)]


💡 توضیح کد:
- customFilter یه تابع مرتبه بالاست که یک predicate (تابع Boolean) می‌گیره.
- داخل بدنه لیست رو پیمایش می‌کنه و اونایی که شرط رو دارند برمی‌گردونه.
- خیلی شبیه filter خود Kotlin هستش، ولی اینجا خودت پیاده‌سازی کردی.

📌 نتیجه‌گیری و نکته حرفه‌ای:
تابع‌های مرتبه بالا باعث می‌شوند کدت قابل استفاده مجدد و انعطاف‌پذیر بشه.
همیشه سعی کن منطق تکراری رو به صورت lambda یا reference به تابع بدی به جای تکرار حلقه‌ها.

#Kotlin #HigherOrderFunctions #Codeit #Android #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🧠 ذهنیت دولوپر یعنی عادت‌هایی که کدت رو از «فقط کار میکنه» به «حرفه‌ای» تبدیل می‌کنه! 🚀

وقتی با چالش مواجه میشی، به جای سریع‌ترین راه، دنبال راهی باش که مقیاس‌پذیر و آزمایش‌پذیر باشه. مثلاً مدیریت خطا با Result توی Kotlin.

فرض کن یه API داری که ممکنه خطا بده. ذهنیت درست اینه که از null استفاده نکنی، بلکه از Result برای نمایش موفقیت یا شکست استفاده کنی.

مثال ساده:
sealed class ApiResult<out T> {
data class Success<T>(val data: T) : ApiResult<T>()
data class Error(val message: String, val exception: Throwable? = null) : ApiResult<Nothing>()
}

fun fetchUser(id: Int): ApiResult<User> {
return try {
val user = api.getUser(id)
ApiResult.Success(user)
} catch (e: Exception) {
ApiResult.Error("خطا در دریافت کاربر", e)
}
}


این کد بهت اجازه میده خطاها رو جدا از منطق اصلی مدیریت کنی و تست‌پذیری کدت بالا میره. 🧪

ذهنیت دولوپر یعنی:
- همیشه به فکر لبه‌ها و خطاهای غیرمنتظره باش.
- کدت رو برای آینده‌ی خودت یا تیمت شفاف بنویس.
- از ابزارهای Jetpack مثل ViewModel برای جداسازی منطق استفاده کن.

جمع‌بندی: هر خط کد یه تصمیمه. بهترین تصمیم رو بگیر! 🎯

#Android #Kotlin #Jetpack #CleanCode #Codeit

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1
🔍 جنریک‌ها توی Kotlin چی هستن؟

جنریک‌ها به شما اجازه می‌دن کلاس‌ها، توابع و اینترفیس‌هایی بنویسید که با انواع داده‌های مختلف کار کنن بدون اینکه مجبور باشید کد تکراری بنویسید. 🎯

مثال عملی: یه مخزن داده که هر نوعی رو ذخیره کنه

class Repository<T>(private val initialValue: T) {
private var data = initialValue

fun getData(): T = data

fun updateData(newData: T) {
data = newData
}
}

// استفاده:
val stringRepo = Repository("Hello")
val intRepo = Repository(42)


این کد چیکار می‌کنه؟
کلاس Repository<T> یه جنریک تعریف می‌کنه که نوع T موقع استفاده مشخص می‌شه. تابع getData مقدار ذخیره شده رو برمی‌گردونه و updateData مقدار جدید می‌ذاره. اینطوری با یه کلاس هم برای استرینگ و هم برای اینتجر کار می‌کنیم.

چرا مفیده؟
بدون جنریک مجبور بودی برای هر نوع کلاس جدا بنویسی یا از Any استفاده کنی که امنیت نوع رو از دست می‌دی.
جنریک‌ها type-safety رو تضمین می‌کنن و کد reusable می‌شه.

نکته مهم: از out و in برای واریانس استفاده کنید تا انعطاف‌پذیری بیشتری داشته باشید. مثلاً List<out T> یا Comparable<in T>.

#Generics #Kotlin #Android #TypeSafety #Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1
🔥 مدیریت خطاهای زمان اجرا در کاتلین، یه مهارت حیاتیه که کدت رو حرفه‌ای و مقاوم می‌کنه!

اگه تا حالا برنامه‌ات موقع کار با کاربر کرش کرده، وقتشه با try-catch و دوستای جدیدش آشنا بشی. 🛡️

بدون مدیریت خطا، کل اپلیکیشن می‌تونه به خاطر یه دونه کاربر بی‌دقت از کار بیفته.

کاتلین علاوه بر try-catch کلاسیک، چند تا ابزار جذاب داره: runCatching و Result مخصوصاً تو کدهای غیرهمزمان یا زمانی که می‌خوای نتیجه رو به صورت امن برگردونی.

بیا یه مثال کاربردی ببینیم:

data class User(val id: Int, val name: String)

fun fetchUserFromServer(userId: Int): Result<User> {
return runCatching {
// شبیه‌سازی درخواست شبکه
if (userId <= 0) throw IllegalArgumentException("Invalid ID: $userId")
User(userId, "Ali")
}
}

fun displayUser(userId: Int) {
val result = fetchUserFromServer(userId)
result.onSuccess { user ->
println(" User found: ${user.name}")
}.onFailure { error ->
println(" Error: ${error.message}")
}
}

// تست
displayUser(1) // User found: Ali
displayUser(-5) // Error: Invalid ID: -5


اینجا runCatching خطا رو می‌گیره و به جای کرش، نتیجه رو به صورت Result برمی‌گردونه. با onSuccess و onFailure می‌تونی هر سناریو رو جدا مدیریت کنی.

💡 بهترین روش: همیشه از runCatching در توابعی که احتمال خطا دارن استفاده کن، مخصوصاً تو لایه repository یا شبکه. اینطوری UI ات هیچوقت کرش نمی‌کنه و کاربر یه پیام مناسب می‌بینه.

#ExceptionHandling #Kotlin #AndroidDev #CleanCode #ErrorManagement #Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🧠 ذهنیت حل مسئله؛ سلاح مخفی یک برنامه‌نویس واقعی
بزرگ‌ترین اشتباه تازه‌کارها اینه که فکر می‌کنن برنامه‌نویس خوب کسیه که همه چیز رو بلده.
اما حقیقت چیز دیگه‌ای هست: برنامه‌نویس حرفه‌ای کسیه که نمی‌ترسه از «نمی‌دونم» و دقیقاً می‌دونه چطور از اون نقطه به جواب برسه.

🔍 مشکل واقعی کد نیست، ترس از روبرو شدن با ابهامه
اکثر ما وقتی به یه باگ عجیب یا یه feature جدید می‌رسیم، اولش استرس می‌گیریم. مغز می‌گه: «نمی‌تونم» یا «این خیلی پیچیده‌ست».
اما اگه ذهنیت رو عوض کنیم و به جاش بگیم: «خب، الان ۵ تا سوال دارم، جوابشون رو پیدا می‌کنم» — ناگهان همه چیز ساده‌تر می‌شه.

💡 یه مثال واقعی: وقتی کلاس Room در اندروید کرش می‌ده
فرض کن داری یه اپلیکیشن با Jetpack Compose می‌سازی. ناگهان صفحه خالی می‌مونه و خطای «Room cannot verify the data integrity» می‌بینی.
آدم معمولی panic می‌کنه و کد رو پاک می‌کنه. اما برنامه‌نویس با ذهنیت حل مسئله:
۱. آروم می‌گیره
۲. خطا رو می‌خونه (نه اینکه سریع اسکرول کنه)
۳. سوال می‌پرسه: «آخرین تغییری که توی دیتابیس دادم چی بود؟»
۴. migration رو چک می‌کنه → متوجه می‌شه schema جدید با قدیمی هماهنگ نیست
۵. یه migration ساده اضافه می‌کنه و مشکل حل می‌شه

تمرین عملی برای امروز
دفعه بعد که به خطا برخوردی، به جای تایپ کردن توی گوگل، اول سه سوال از خودت بپرس:
- چه انتظاری داشتم که برآورده نشد؟
- کوچک‌ترین قدم برای فهمیدن دلیل چیه؟
- آیا تا حالا این مشکل رو جایی دیدم یا مشابهش رو؟

این سه سوال، ذهن تو رو از حالت وحشت به حالت کاوشگر تغییر می‌ده. 🚀

📌 نتیجه‌گیری
برنامه‌نویسی یه ماراتن حافظه‌ نیست؛ یه مسابقه‌ی حل مسئله‌ست. هرچی بیشتر تمرین کنی که در ناآرامی آرام بمانی و قدم‌های کوچک برداری، حرفه‌ای‌تر می‌شی.

#ProblemSolving #GrowthMindset #DeveloperJourney #CleanCode #AndroidDev #Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
سلام! 🚀 امروز می‌خوایم با While Loop در کاتلین آشنا بشیم. یک ابزار ساده و قدرتمند برای تکرار کارها تا زمانی که شرط برقرار باشه.

While Loop چه جوریه؟
- تا وقتی شرط true باشه، بلاک داخلش اجرا می‌شه.
- اگر شرط اولیه false باشه، حتی یک بار هم اجرا نمی‌شه.
- برای حلقه‌هایی که تعداد تکرارش رو از قبل نمی‌دونیم عالیه.

مثال کاربردی: فرض کن می‌خوایم از کاربر عدد ورودی بگیریم تا وقتی عدد مثبت وارد کنه، مجموع رو حساب کنیم.

var sum = 0
var number: Int

while (true) {
println("یک عدد وارد کنید (عدد منفی برای خروج):")
number = readLine()?.toIntOrNull() ?: 0
if (number < 0) break
sum += number
}
println("مجموع اعداد وارد شده: $sum")


این کد تا وقتی عدد منفی وارد نشده، اعداد رو جمع می‌کنه و بعد نمایش می‌ده.
break برای خروج از حلقه استفاده شده.

نکته: همیشه مطمئن باش حلقه متناهی هست، وگرنه برنامه هنگ می‌کنه!

#WhileLoop #KotlinBasics #Looping #AndroidDev #Programming #Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1
🔹 توابع (Functions) در کاتلین چطور کار می‌کنن؟ 🤔

تابع یه قطعه کد قابل استفاده دوباره است که کار مشخصی رو انجام میده. مثل یه دستیار که هر وقت صداش می‌کنی، وظیفش رو انجام میده.

⚡️ ساده‌ترین شکل تابع در کاتلین:
- با fun شروع میشه
- اسم تابع
- پرانتز برای ورودی‌ها (حتی خالی)
- بدنه داخل آکولاد

مثلاً تابعی که دو عدد رو جمع می‌کنه و برمی‌گردونه:

fun sum(a: Int, b: Int): Int {
return a + b
}

// استفاده:
val result = sum(5, 3)
println(result) // خروجی: 8


تابع sum دو ورودی از نوع Int می‌گیره و یه Int برمی‌گردونه. کلمه return مقدار رو به صدا‌زننده برمی‌گردونه.

💡 نکته جالب: کاتلین بهت اجازه میده توابع رو خیلی خلاصه‌تر هم بنویسی! به این میگن expression function:

fun multiply(x: Int, y: Int) = x * y

println(multiply(4, 5)) // خروجی: 20


در اینجا نیازی به return و آکولاد نیست. خود کاتلین مقدار آخر رو برمی‌گردونه.

🎯 کاربرد عملی: فرض کن توی اپت می‌خوای قیمت کالا رو با تخفیف محاسبه کنی. می‌تونی یه تابع بنویسی:

fun priceWithDiscount(originalPrice: Double, discountPercent: Double): Double {
val discountAmount = originalPrice * (discountPercent / 100)
return originalPrice - discountAmount
}

val finalPrice = priceWithDiscount(1000.0, 15.0)
println(finalPrice) // 850.0


📌 نکته مهم: اسم تابع باید واضح و گویا باشه تا بعداً کدت رو راحت‌تر بخونی.

🚀 برداشت عملی: توابع رو برای کارهای تکراری بساز. هم کدت خواناتر میشه و هم اشکال‌زدایی راحت‌تر.

#Kotlin #Functions #AndroidDev #Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1
🧬 وراثت در کاتلین — اصولی فراتر از کلاس پدر

وراثت یکی از مفاهیم اصلی برنامه‌نویسی شی‌گراست. تو کاتلین برخلاف جاوا، کلاس‌ها به‌طور پیش‌فرض final هستن و برای اینکه بشه ازشون ارث‌بری کرد باید با open مشخصشون کنی. 🎯

چرا وراثت؟
وقتی چند کلاس رفتار یا ویژگی مشترک دارن، می‌تونی اون‌ها رو تو یه کلاس پایه (Base) بذاری و بقیه کلاس‌ها ازش ارث‌ببرن. این کار از تکرار کد جلوگیری می‌کنه و نگهداری رو آسون‌تر می‌کنه. 🔄

📦 یه مثال واقعی: مدیریت کاربران
فرض کن اپلیکیشنی داری که هم کاربر عادی (RegularUser) داری هم کاربر ویژه (PremiumUser). هر دو اسم و ایمیل دارن، ولی کاربر ویژه مزایای بیشتری داره.

open class User(val name: String, val email: String) {
open fun login() = "$name با موفقیت وارد شد."
}

class RegularUser(name: String, email: String) : User(name, email)

class PremiumUser(name: String, email: String, val discount: Int) : User(name, email) {
override fun login() = "$name (VIP) با تخفیف ${discount}% وارد شد."
}


💡 توضیح کد:
کلاس User با open اومده تا بشه ازش ارث‌برد. متد login هم open هست تا در کلاس‌های فرزند بازنویسی (override) بشه. حالا هر نوع کاربر به‌طور اختصاصی می‌تونه وارد بشه. این یعنی کد تمیزتر و توسعه‌پذیرتر.

📌 نکته مهم:
تو کاتلین وراثت فقط از یک کلاس مجازه (Single Inheritance). برای رفتارهای مشترک بین چند کلاس بهتره از Interface استفاده کنی.

توصیه عملی:
همیشه قبل از استفاده از وراثت از خودت بپرس: «آیا رابطه «is-a» واقعاً بین این کلاس‌ها برقراره؟» اگه جواب آره، وراثت انتخاب خوبیه. در غیر این صورت به سراغ Composition برو. 🧠

#Inheritance #Kotlin #OOP #AndroidDev #Codeit #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
عادت کوچیک روزانه، بزرگترین تغییر رو میسازه؟ 🌱

خیلی از توسعه‌دهنده‌ها منتظر یه «جرقه» یا «دوره فشرده» می‌مونن تا پیشرفت کنن. اما حقیقت اینه که رشد واقعی توی برنامه‌نویسی، نتیجه هزاران عادت کوچیک و روزانست.

یه قانون ساده: هر روز ۲۰ دقیقه وقت بذار برای یه چیز جدید. نه بیشتر. این کار مغزت رو به یادگیری مداوم عادت میده، بدون اینکه خسته بشی.

مثلاً تصمیم بگیر هر روز یه تابع جدید از Kotlin رو توی یه پروژه آزمایشی امتحان کنی. توی یک ماه، ۳۰ تا ابزار جدید یاد گرفتی.

نکته مهم: این عادت رو با یه «محرک» ثابت شروع کن. مثلاً بعد از خوردن قهوه صبحگاهی، ۱۵ دقیقه کد بزن. تکرار باعث خودکار شدنش میشه.

🔥 نتیجه: به جای جهش‌های بزرگ گاه‌به‌گاه، پیشرفت آروم و پایدار رو انتخاب کن.

حرف آخر: هر روز حداقل ۱۵ دقیقه کد بزن، حتی اگه پروژه‌ت بی‌معنی باشه. این همون تفاوت بین یه برنامه‌نویس معمولی و یه حرفه‌ایه.

#Codeit #Android #Kotlin #Mindset #DailyHabit
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1