CodeBlanks Logo Icon CodeBlanks

Exposed DB

Exposed ile veritabanı katmanı yazarsın.

UsersTable ile DB soyutlama

Üçüncü ders, UsersTable adında bir object ekler. Bu, Exposed'ın tablo soyutlamasını küçük çapta taklit eder. UserRepo artık doğrudan liste yerine UsersTable'ı kullanır.

Örnek: object UsersTable { val rows = mutableListOf<User>(); fun insert(u) { rows.add(u) }; fun select(id) = rows.find { it.id == id } }. UserRepo.save artık UsersTable.insert(u) çağırır. Bu ayrım, iş mantığı ile veri katmanını ayırır.

UserRepo ve UsersTable ayrımı

UserRepo iş mantığını, UsersTable veri saklamayı yönetir. Bu ayrım, ileride tablonun gerçek bir veritabanına değiştirilmesini kolaylaştırır. Test sırasında UsersTable sahte bir uygulama ile değiştirilebilir; repoyu aynı tutarak davranışı izole edersin.

Örnek: UserRepo.save(u) { UsersTable.insert(u) }. UserRepo.find(id) { UsersTable.select(id) }. Repoyu değiştirmeden UsersTable'ı gerçek DB'ye bağlayabilirsin. Bu kalıp, katmanlı mimarinin temelidir.

Uygulama UsersTable ekle ve UserRepo'yu bağla

Mevcut User, UserRepo ve Api tanımlarını koru. object UsersTable ekle; val rows = mutableListOf<User>(), fun insert(u: User) ve fun select(id: Int): User? olsun. UserRepo'nun save ve find metotlarını UsersTable.insert ve UsersTable.select çağıracak şekilde değiştir. main aynı kalsın: repo.save(User(1, "Ayşe")) ve println(api.route("/users/1")).

Başlangıç kodu

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

class UserRepo {
    private val users = mutableListOf<User>()
    fun save(u: User) { users.add(u) }
    fun find(id: Int): User? = users.find { it.id == id }
}

class Api(val repo: UserRepo) {
    fun route(path: String): String {
        return when {
            path.startsWith("/users/") -> {
                val id = path.removePrefix("/users/").toInt()
                repo.find(id)?.name ?: "not found"
            }
            else -> "404"
        }
    }
}

fun main() {
    val repo = UserRepo()
    repo.save(User(1, "Ayşe"))
    val api = Api(repo)
    println(api.route("/users/1"))
}

// UsersTable object ekle, UserRepo'yu ona bağla
// main aynı kalsın

Örnek çözüm

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

object UsersTable {
    val rows = mutableListOf<User>()
    fun insert(u: User) { rows.add(u) }
    fun select(id: Int): User? = rows.find { it.id == id }
}

class UserRepo {
    fun save(u: User) { UsersTable.insert(u) }
    fun find(id: Int): User? = UsersTable.select(id)
}

class Api(val repo: UserRepo) {
    fun route(path: String): String {
        return when {
            path.startsWith("/users/") -> {
                val id = path.removePrefix("/users/").toInt()
                repo.find(id)?.name ?: "not found"
            }
            else -> "404"
        }
    }
}

fun main() {
    val repo = UserRepo()
    repo.save(User(1, "Ayşe"))
    val api = Api(repo)
    println(api.route("/users/1"))
}

Beklenen çıktı

Ayşe

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 UsersTable parçalarını eşle

Kavram Anlamı
object UsersTable Singleton tablo
rows Satır listesi
insert(u) Ekleme
select(id) Sorgu

2 UserRepo ile UsersTable arasındaki ayrımın temel nedeni nedir?

  • Hızı artırmak
  • Test gerektirmemek
  • Daha az kod yazmak
  • Katmanlı mimari Doğru cevap

Açıklama: Ayrım katmanlı mimari sağlar.

3 object UsersTable tanımını tamamla

Soru
____ UsersTable { val rows = mutableListOf<User>() }
Cevap
object UsersTable { val rows = mutableListOf<User>() }

Açıklama: object UsersTable singleton tablo tanımlar.

İleri seviye bölümündeki tüm dersler