0Pricing
Kotlin Academy · Aula

Delegados observable e vetoable

Reaja a alterações de propriedades com observable e rejeite-as condicionalmente com vetoable.

Delegados observable e vetoable é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.

Revisão dos delegados de propriedades

Os delegados de propriedades do Kotlin permitem que um objeto separado controle getValue e setValue. Delegates.observable e Delegates.vetoable são delegados integrados da biblioteca padrão.

import kotlin.properties.Delegates
var name: String by Delegates.observable("initial") { prop, old, new ->
    println("${prop.name}: $old -> $new")
}
fun main() { name = "Alice"; name = "Bob" }

Sintaxe de observable

observable recebe um valor inicial e uma função de retorno chamada após cada alteração, com a propriedade, o valor antigo e o novo valor.

import kotlin.properties.Delegates
var score: Int by Delegates.observable(0) { _, old, new ->
    println("Score changed from $old to $new")
}
fun main() {
    score = 10
    score = 25
    score = 0
}

Disparando atualizações da interface

Os delegados observáveis são excelentes para disparar a atualização da interface do usuário quando uma propriedade de suporte muda, sem configurar completamente o LiveData.

import kotlin.properties.Delegates
class ViewModel {
    var title: String by Delegates.observable("Loading") { _, _, new ->
        println("Render: $new") // pretend this updates UI
    }
}
fun main() {
    val vm = ViewModel()
    vm.title = "Home"
    vm.title = "Settings"
}

Sintaxe de vetoable

vetoable chama uma função de retorno antes da atribuição. Se a função retornar false, o novo valor será rejeitado e o valor antigo será mantido.

import kotlin.properties.Delegates
var age: Int by Delegates.vetoable(0) { _, old, new ->
    new >= 0 // reject negative ages
}
fun main() {
    age = 25; println(age)  // 25
    age = -1; println(age)  // 25 (rejected)
    age = 30; println(age)  // 30
}

Combinando validação com vetoable

Use vetoable para impor invariantes do domínio no nível da propriedade, sem lógica de validação externa.

import kotlin.properties.Delegates
var email: String by Delegates.vetoable("") { _, _, new ->
    new.contains("@")
}
fun main() {
    email = "user@example.com"; println(email) // set
    email = "invalid";          println(email) // still previous
}

Registrando alterações com observable

Use observable para registro de auditoria: registre automaticamente cada transição de estado sem alterar a lógica de negócio.

import kotlin.properties.Delegates
val log = mutableListOf<String>()
var status: String by Delegates.observable("IDLE") { _, old, new ->
    log.add("$old -> $new")
}
fun main() {
    status = "RUNNING"
    status = "DONE"
    println(log)
}

observable em uma classe

Ambos os delegados funcionam dentro dos corpos das classes, assim como qualquer outra propriedade.

import kotlin.properties.Delegates
class Counter {
    var count: Int by Delegates.observable(0) { _, old, new ->
        if (new > old) println("Incremented to $new")
        else println("Decremented to $new")
    }
}
fun main() {
    val c = Counter()
    c.count = 5
    c.count = 3
}

vetoable para restrição de intervalo

Restrinja uma propriedade numérica a um intervalo válido usando vetoable.

import kotlin.properties.Delegates
var volume: Int by Delegates.vetoable(50) { _, _, new ->
    new in 0..100
}
fun main() {
    volume = 80;  println(volume) // 80
    volume = 150; println(volume) // 80 (rejected)
    volume = 0;   println(volume) // 0
}

Encadeando delegados

Você pode combinar manualmente a lógica de observable escrevendo um delegado personalizado que chama observable internamente e adiciona lógica a cada etapa.

import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
class LoggedDelegate<T>(initial: T) : ReadWriteProperty<Any?, T> {
    private var value: T = initial
    override fun getValue(t: Any?, p: KProperty<*>) = value
    override fun setValue(t: Any?, p: KProperty<*>, v: T) {
        println("Setting ${p.name} = $v"); value = v
    }
}
var x: Int by LoggedDelegate(0)
fun main() { x = 10; x = 20 }

Observação sobre segurança entre threads

Nem observable nem vetoable é seguro para threads por padrão. Para acesso concorrente, proteja as mutações com um mutex ou sincronize externamente.

import kotlin.properties.Delegates
// Not thread-safe as-is:
var sharedState: String by Delegates.observable("start") { _, old, new ->
    println("$old -> $new")
}
// In coroutines, wrap access with Mutex if needed

Padrão prático: validação de formulário

Use vetoable em cada campo para validação declarativa de formulário: cada campo valida a si mesmo no momento da atribuição.

import kotlin.properties.Delegates
data class Form(
    var username: String = "",
    var password: String = ""
) {
    var validUsername: String by Delegates.vetoable("") { _,_,v -> v.length >= 3 }
    var validPassword: String by Delegates.vetoable("") { _,_,v -> v.length >= 8 }
}
fun main() {
    val f = Form()
    f.validUsername = "ab";       println(f.validUsername) // ""
    f.validUsername = "alice";    println(f.validUsername) // "alice"
    f.validPassword = "short";    println(f.validPassword) // ""
    f.validPassword = "secure123";println(f.validPassword) // "secure123"
}

Verificação rápida

Quando vetoable chama sua função de retorno?

Recapitulação

observable notifica após cada alteração; vetoable é executado antes da atribuição e pode rejeitar o novo valor. Ambos são excelentes para registro, validação e padrões de propriedades reativas sem bibliotecas externas.

Perguntas Frequentes

A aula “Delegados observable e vetoable” é grátis?

Sim — o texto completo de “Delegados observable e vetoable” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.

O que vou aprender em “Delegados observable e vetoable”?

Reaja a alterações de propriedades com observable e rejeite-as condicionalmente com vetoable. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Kotlin Academy?

Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Delegados observable e vetoable”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Kotlin Academy?

Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. by lazy: análise detalhada da inicialização adiada
  2. Delegados observable e vetoable
  3. Escrevendo um delegado ReadWriteProperty personalizado
  4. Delegados para preferências, propriedades baseadas em mapas e registro
← Voltar para Kotlin Academy