Event Bus e padrão Observer em Kotlin: arquitetura de aplicações orientadas a eventos
O desenvolvimento moderno em Kotlin, especialmente no contexto de Android e aplicações servidoras, exige mecanismos flexíveis de interação entre componentes. O padrão Observer e sua implementação prática — Event Bus — oferecem uma solução elegante para arquiteturas fracamente acopladas, onde um objeto (publicador) notifica múltiplos assinantes sobre a ocorrência de um evento, sem conhecer sua implementação específica. Neste artigo, vamos analisar como construir seu próprio Event Bus em Kotlin, usando corrotinas e tipagem segura.
Padrão Observer: base teórica
O padrão Observer (Observador) define uma dependência "um para muitos" entre objetos. Quando o estado do sujeito (publicador) muda, todos os objetos dependentes (observadores) são automaticamente notificados e atualizados. Em Kotlin, esse padrão pode ser implementado por meio de interfaces, lambdas ou construções mais avançadas.
Elementos-chave do padrão:
- Subject (Sujeito) — objeto que gerencia a lista de observadores e envia notificações.
- Observer (Observador) — objeto que recebe notificações do sujeito.
- ConcreteSubject — implementação concreta do sujeito com seu próprio estado.
- ConcreteObserver — implementação concreta do observador, reagindo a mudanças.
Exemplo de implementação simples em Kotlin:
interface Observer { fun update(event: String)}
class ConcreteSubject { private val observers = mutableListOf<Observer>()
fun attach(observer: Observer) { observers.add(observer) }
fun detach(observer: Observer) { observers.remove(observer) }
fun notifyObservers(event: String) { observers.forEach { it.update(event) } }}
class ConcreteObserver(private val name: String) : Observer { override fun update(event: String) { println("$name recebeu o evento: $event") }}
fun main() { val subject = ConcreteSubject() val observer1 = ConcreteObserver("Observador 1") val observer2 = ConcreteObserver("Observador 2")
subject.attach(observer1) subject.attach(observer2) subject.notifyObservers("Dados atualizados")}Event Bus: barramento de eventos prático
Event Bus é um mecanismo centralizado que estende o padrão Observer. Em vez de cada sujeito gerenciar seus próprios observadores, é criado um barramento único por onde passam todos os eventos. Isso simplifica a comunicação entre componentes, especialmente em aplicações complexas.
Vantagens do Event Bus:
- Baixo acoplamento: publicadores e assinantes não se conhecem.
- Facilidade para adicionar novos assinantes sem alterar o código existente.
- Possibilidade de filtrar eventos por tipo ou tag.
- Suporte a processamento assíncrono por meio de corrotinas.
Implementação de Event Bus em Kotlin com corrotinas
Uma implementação moderna de Event Bus deve considerar concorrência e evitar vazamentos de memória. O uso de Coroutines e Channel permite criar um barramento seguro para threads e eficiente.
Implementação básica do Event Bus:
import kotlinx.coroutines.*import kotlinx.coroutines.channels.Channelimport kotlinx.coroutines.flow.*
sealed class Event { data class UserLoggedIn(val userId: String) : Event() data class DataUpdated(val data: String) : Event() object NetworkError : Event()}
class EventBus { private val _events = MutableSharedFlow<Event>(extraBufferCapacity = 64) val events: SharedFlow<Event> = _events.asSharedFlow()
suspend fun publish(event: Event) { _events.emit(event) }
fun subscribe(scope: CoroutineScope, action: (Even