O que é Delegation em Kotlin?
Delegation (delegação) é um padrão de design onde um objeto repassa responsabilidades para outro. Em Kotlin, a delegação é suportada nativamente com a palavra-chave by, tanto para classes quanto para propriedades.
Em vez de herdar de uma classe, você delega a implementação para uma instância. É o famoso princípio “composição sobre herança” que fica muito fácil de aplicar em Kotlin.
Delegação de classe
interface Repositorio {
fun salvar(dados: String)
fun buscar(): String
}
class RepositorioBanco : Repositorio {
override fun salvar(dados: String) = println("Salvando no banco: $dados")
override fun buscar() = "Dados do banco"
}
class RepositorioComLog(repo: Repositorio) : Repositorio by repo {
override fun salvar(dados: String) {
println("[LOG] Operação de salvar iniciada")
// Delega para o repositório original, mas não automaticamente neste override
}
// buscar() é delegado automaticamente
}
fun main() {
val repo = RepositorioComLog(RepositorioBanco())
println(repo.buscar()) // Dados do banco
repo.salvar("teste") // [LOG] Operação de salvar iniciada
}
O by repo faz com que todos os métodos da interface sejam delegados automaticamente. Você só sobrescreve o que quiser customizar.
Delegação de propriedade
Kotlin oferece delegates prontos pra uso:
import kotlin.properties.Delegates
class Configuracao {
// Inicialização preguiçosa
val conexao: String by lazy {
println("Conectando ao banco...")
"Conexão estabelecida"
}
// Observável — executa bloco quando muda
var tema: String by Delegates.observable("claro") { _, antigo, novo ->
println("Tema mudou de '$antigo' para '$novo'")
}
// Não pode ser lido antes de ser atribuído
var usuario: String by Delegates.notNull()
}
fun main() {
val config = Configuracao()
println(config.conexao) // "Conectando..." + "Conexão estabelecida"
println(config.conexao) // "Conexão estabelecida" (já inicializou)
config.tema = "escuro" // Tema mudou de 'claro' para 'escuro'
config.usuario = "Karina"
println(config.usuario) // Karina
}
Criando seu próprio delegate
import kotlin.reflect.KProperty
class FormatadoDelegate {
private var valor = ""
operator fun getValue(thisRef: Any?, property: KProperty<*>): String = valor
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
valor = value.trim().lowercase()
}
}
class Formulario {
var email: String by FormatadoDelegate()
}
fun main() {
val form = Formulario()
form.email = " KARINA@Email.COM "
println(form.email) // karina@email.com
}
Delegation em Kotlin é poderoso pra reduzir boilerplate, adicionar comportamentos transversais e manter o código organizado.