Delegated Properties in Kotlin (#2357)

This produces a fake Database representation - working in terms of
hardcoded data, a Delegate that loads values from this fake Database,
and then a class with fields delegated to the fake database.
This commit is contained in:
Graham Cox 2017-08-02 18:42:13 +01:00 committed by Grzegorz Piwowarek
parent f02d117223
commit 8137c20349
4 changed files with 80 additions and 0 deletions

View File

@ -0,0 +1,35 @@
package com.baeldung.kotlin.delegates
val data = arrayOf<MutableMap<String, Any?>>(
mutableMapOf(
"id" to 1,
"name" to "George",
"age" to 4
),
mutableMapOf(
"id" to 2,
"name" to "Charlotte",
"age" to 2
)
)
class NoRecordFoundException(id: Int) : Exception("No record found for id $id") {
init {
println("No record found for ID $id")
}
}
fun queryForValue(field: String, id: Int): Any {
println("Loading record $id from the fake database")
val value = data.firstOrNull { it["id"] == id }
?.get(field) ?: throw NoRecordFoundException(id)
println("Loaded value $value for field $field of record $id")
return value
}
fun update(field: String, id: Int, value: Any?) {
println("Updating field $field of record $id to value $value in the fake database")
data.firstOrNull { it["id"] == id }
?.put(field, value)
?: throw NoRecordFoundException(id)
}

View File

@ -0,0 +1,13 @@
package com.baeldung.kotlin.delegates
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class DatabaseDelegate<in R, T>(private val field: String, private val id: Int) : ReadWriteProperty<R, T> {
override fun getValue(thisRef: R, property: KProperty<*>): T =
queryForValue(field, id) as T
override fun setValue(thisRef: R, property: KProperty<*>, value: T) {
update(field, id, value)
}
}

View File

@ -0,0 +1,6 @@
package com.baeldung.kotlin.delegates
class User(val id: Int) {
var name: String by DatabaseDelegate("name", id)
var age: Int by DatabaseDelegate("age", id)
}

View File

@ -0,0 +1,26 @@
package com.baeldung.kotlin.delegates
import org.junit.Test
import kotlin.test.assertEquals
class DatabaseDelegatesTest {
@Test
fun testGetKnownFields() {
val user = User(1)
assertEquals("George", user.name)
assertEquals(4, user.age)
}
@Test
fun testSetKnownFields() {
val user = User(2)
user.age = 3
assertEquals(3, user.age)
}
@Test(expected = NoRecordFoundException::class)
fun testGetKnownField() {
val user = User(3)
user.name
}
}