Kotlin delegation is a powerful feature that allows an object to delegate its responsibilities to another object. This approach promotes code reuse and cleaner architecture. In Kotlin, delegation can be implemented using the by
keyword, making it simpler to compose behaviors without inheritance. Below are three practical examples of Kotlin delegation that demonstrate its versatility in real-world applications.
Lazy initialization is a design pattern that defers the creation of an object until it is needed. This can improve performance and resource management, especially for expensive objects.
class User(val name: String) {
// Property to be initialized lazily
val email: String by lazy { fetchEmailFromDatabase() }
private fun fetchEmailFromDatabase(): String {
// Simulate a delay to fetch email
Thread.sleep(1000)
return "$name@example.com"
}
}
fun main() {
val user = User("John")
println("User created: ${user.name}") // Outputs immediately
println("Email: ${user.email}") // Fetches email after 1 second
}
fetchEmailFromDatabase
function is only called when email
is accessed for the first time.Observable properties allow changes to be tracked and handled automatically. This is particularly useful in UI development where changes in the underlying data should reflect in the user interface.
import kotlin.properties.Delegates
class UserProfile {
var name: String by Delegates.observable("Unknown") { property, oldValue, newValue ->
println("Name changed from \(oldValue to \)newValue")
}
}
fun main() {
val profile = UserProfile()
profile.name = "Alice" // Outputs: Name changed from Unknown to Alice
profile.name = "Bob" // Outputs: Name changed from Alice to Bob
}
Delegates.observable
function takes an initial value and a lambda function to handle changes.In certain cases, you may want to create read-only properties that are backed by another object. This is useful when you want to expose some functionality while hiding the implementation details.
interface Logger {
fun log(message: String)
}
class ConsoleLogger : Logger {
override fun log(message: String) {
println("Log: $message")
}
}
class Application(logger: Logger) {
private val logger: Logger by lazy { logger }
fun execute() {
logger.log("Application is starting...")
// Application logic here
logger.log("Application has finished running.")
}
}
fun main() {
val app = Application(ConsoleLogger())
app.execute()
}
Application
class delegates logging to the Logger
interface, allowing for different logging implementations.These examples of Kotlin delegation illustrate how this feature can streamline code organization and enhance functionality in various programming scenarios.