19

پروژه عملی: Todo CLI کوچیک اما با شخصیت

تا پروژه نزنی، دانشت مثل کفش نوئه؛ قشنگه ولی هنوز راه نرفته.

درس 19 از 20

مدل داده

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

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

Todo model
data class Todo(
    val id: Int,
    val title: String,
    var done: Boolean = false
)
خروجی یا نتیجه اجرا
خروجی مستقیم ندارد؛ این مدل داده پایه‌ی Todoهاست.
نکته کاربردی: این بخش اسکلت ذهنی درس را می‌سازد. وقتی بدانی این قطعه دقیقاً چه مسئله‌ای را حل می‌کند، بعداً موقع پروژه فقط syntax حفظی تحویل نمی‌دهی؛ تصمیم درست می‌گیری. اگر خروجی با چیزی که انتظار داشتی فرق کرد، اول مقدار متغیرها و مسیر اجرا را چک کن؛ ۹۰٪ باگ‌های اول راه همین‌جا قایم شده‌اند.

مدیریت لیست

برای نمونه آموزشی از `MutableList` استفاده می‌کنیم. در پروژه واقعی ممکنه دیتابیس، فایل یا API داشته باشی؛ ولی اول مغز منطق رو بفهم.

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

TodoManager
class TodoManager {
    private val todos = mutableListOf<Todo>()
    private var nextId = 1

    fun add(title: String) {
        todos.add(Todo(nextId++, title))
    }

    fun complete(id: Int) {
        todos.find { it.id == id }?.done = true
    }

    fun list(): List<Todo> = todos
}
خروجی یا نتیجه اجرا
خروجی مستقیم ندارد؛ TodoManager عملیات add، complete و list را آماده می‌کند.
نکته کاربردی: اینجا باید به رفتار کد نگاه کنی، نه فقط ظاهرش. مقدارها را عوض کن و دوباره اجرا بگیر تا دستت بفهمد برنامه چطور واکنش نشان می‌دهد. اگر خروجی با چیزی که انتظار داشتی فرق کرد، اول مقدار متغیرها و مسیر اجرا را چک کن؛ ۹۰٪ باگ‌های اول راه همین‌جا قایم شده‌اند.

اجرای ساده

حالا چند کار اضافه می‌کنیم و خروجی می‌گیریم. این پروژه کوچیکه ولی مفاهیم مهمی مثل data class، mutable list، تابع و encapsulation رو واقعی تمرین می‌کنی.

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

main
fun main() {
    val manager = TodoManager()
    manager.add("یادگیری Kotlin")
    manager.add("زدن پروژه واقعی")
    manager.complete(1)

    manager.list().forEach { println(it) }
}
خروجی یا نتیجه اجرا
Todo(id=1, title=یادگیری Kotlin, done=true)
Todo(id=2, title=زدن پروژه واقعی, done=false)
نکته کاربردی: این الگو در پروژه واقعی زیاد تکرار می‌شود. از همین حالا تمیز و خوانا بنویس تا بعداً موقع دیباگ، خودت به خودت فحش ندهی. اگر خروجی با چیزی که انتظار داشتی فرق کرد، اول مقدار متغیرها و مسیر اجرا را چک کن؛ ۹۰٪ باگ‌های اول راه همین‌جا قایم شده‌اند.

چطور حرفه‌ای‌ترش کنیم؟

ورودی کاربر اضافه کن، ذخیره در فایل بگذار، دستور delete بساز، تست بنویس و بعد نسخه API با Ktor بده. کم‌کم همین پروژه ریز می‌تونه رزومه‌ای بشه؛ فقط تنبل‌بازی درنیار.

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

نکته کاربردی: نکته حرفه‌ای این است که Kotlin معمولاً راه کوتاه‌تر دارد، ولی کوتاه‌تر همیشه بهتر نیست. اول خوانایی، بعد زرنگ‌بازی. این توضیح قرار است دید پروژه‌ای بدهد، نه اینکه فقط تعریف کتابی حفظ کنی.

نتیجه این درس 🎯

پروژه Todo کوچک است، ولی همه چیز را به هم وصل می‌کند: مدل، مدیریت لیست، تغییر وضعیت و نمایش خروجی. همین مدل را می‌توانی کم‌کم فایل‌دار، دیتابیسی یا APIدار کنی.

تمرین! 🧠

تابع delete(id) را به TodoManager اضافه کن.

جواب تمرین
class TodoManager {
    private val todos = mutableListOf<Todo>()
    private var nextId = 1

    fun add(title: String) {
        todos.add(Todo(nextId++, title))
    }

    fun delete(id: Int): Boolean {
        return todos.removeIf { it.id == id }
    }

    fun list(): List<Todo> = todos
}
خروجی جواب
خروجی مستقیم ندارد؛ این جواب قابلیت delete را به TodoManager اضافه می‌کند.