kotlinintermediate
Delegation — by, lazy, observable, and Custom
Use Kotlin delegation for reusable behavior: by keyword, lazy, observable, vetoable, and map-backed.
kotlinPress ⌘/Ctrl + Shift + C to copy
import kotlin.properties.Delegates
import kotlin.reflect.KProperty
// Interface delegation (composition over inheritance)
interface Logger {
fun log(message: String)
}
class ConsoleLogger : Logger {
override fun log(message: String) = println("[LOG] $message")
}
class FileLogger : Logger {
override fun log(message: String) = println("[FILE] $message")
}
// Delegate logging behavior
class UserService(logger: Logger) : Logger by logger {
fun createUser(name: String) {
log("Creating user: $name") // Delegated to logger
}
}
// Property delegation
class AppConfig {
// lazy — computed once on first access
val databaseUrl: String by lazy {
println("Computing database URL...")
"jdbc:postgresql://localhost:5432/app"
}
// observable — callback on change
var theme: String by Delegates.observable("light") { _, old, new ->
println("Theme changed: $old → $new")
}
// vetoable — reject invalid values
var fontSize: Int by Delegates.vetoable(14) { _, _, new ->
new in 8..72 // only accept valid sizes
}
// notNull — must be set before first access
var apiKey: String by Delegates.notNull()
}
// Custom delegate
class Trimmed {
private var value: String = ""
operator fun getValue(thisRef: Any?, property: KProperty<*>): String = value
operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
value = newValue.trim()
}
}
// Cached delegate with expiration
class Cached<T>(private val ttlMs: Long, private val compute: () -> T) {
private var cachedValue: T? = null
private var lastComputed: Long = 0
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
val now = System.currentTimeMillis()
if (cachedValue == null || now - lastComputed > ttlMs) {
cachedValue = compute()
lastComputed = now
}
return cachedValue!!
}
}
// Map-backed properties
class MappedUser(map: Map<String, Any?>) {
val name: String by map
val age: Int by map
val email: String by map
}
class Form {
var username: String by Trimmed()
var bio: String by Trimmed()
val timestamp: Long by Cached(5000) { System.currentTimeMillis() }
}
fun main() {
// Interface delegation
val service = UserService(ConsoleLogger())
service.createUser("Alice") // [LOG] Creating user: Alice
// Lazy
val config = AppConfig()
println("Before access") // lazy not computed yet
println(config.databaseUrl) // Now computed
println(config.databaseUrl) // Cached
// Observable
config.theme = "dark" // Theme changed: light → dark
// Vetoable
config.fontSize = 20 // accepted
config.fontSize = 100 // rejected (stays 20)
println("Font size: ${config.fontSize}") // 20
// Custom delegate
val form = Form()
form.username = " alice "
form.bio = " Hello world "
println("'${form.username}'") // 'alice'
println("'${form.bio}'") // 'Hello world'
// Map-backed
val user = MappedUser(mapOf("name" to "Bob", "age" to 25, "email" to "bob@test.com"))
println("${user.name}, ${user.age}") // Bob, 25
}Use Cases
- Composing behavior without deep inheritance
- Lazy initialization of expensive resources
- Validation and formatting via property delegates
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
kotlinintermediate
Class Delegation with by Keyword
Use Kotlin's 'by' keyword for class delegation: interface forwarding, decorated behavior, and composition.
Best for: Decorator pattern with minimal boilerplate
#kotlin#delegation
kotlinbeginner
Delegate Properties to a Map
Store class properties in a map using Kotlin delegation for dynamic and flexible data objects.
Best for: Dynamic configuration from external sources
#kotlin#delegation
kotlinadvanced
Custom Property Delegates
Create reusable property delegates: validation, logging, caching, and thread-safe lazy initialization.
Best for: Input validation on property assignment
#kotlin#delegates
kotlinintermediate
Interface Delegation with 'by'
Delegate interface implementations with the 'by' keyword: composition over inheritance patterns.
Best for: Composition over inheritance
#kotlin#delegation