Pular para o conteúdo

Boas práticas e padrões · Padrões comportamentais · 5 min de leitura

Observer (e fluxos reativos)

Quando um objeto muda, todos os interessados são avisados — a base de LiveData, Flow, RxJS e eventos de UI.

Carrinho → emiteemite → Ícone do carrinhoemite → Tela de resumoemite → AnalyticsCarrinho — StateFlowCarrinhoStateFlowemite — novo estadoemitenovo estadoÍcone do carrinho — badge = 3Ícone do carrinhobadge = 3Tela de resumoTela de resumoAnalyticsAnalytics

Arraste para o lado para ver o diagrama inteiro.

O carrinho não conhece quem o observa: emite o novo estado, e cada observador reage do seu jeito.

O padrão

O sujeito mantém uma lista de observadores e os notifica quando muda. Isso desacopla quem produz a informação de quem reage a ela. Hoje quase sempre usamos a versão "reativa": Flow/StateFlow em Kotlin, Observable no RxJS, signals em frameworks web.

Armadilhas

  • Vazamento de memória: observador que nunca se desinscreve (em Android, colete com repeatOnLifecycle ou collectAsStateWithLifecycle).
  • Cascata de eventos difícil de rastrear — prefira estado único (StateFlow) a muitos eventos soltos.
  • Thread certa: atualize a UI só na main thread.

No código

✓ ExemploKotlin
class CarrinhoRepository {
  private val _itens = MutableStateFlow<List<Item>>(emptyList())
  val itens: StateFlow<List<Item>> = _itens.asStateFlow()
  fun adicionar(i: Item) = _itens.update { it + i }
}

class CarrinhoViewModel(repo: CarrinhoRepository) : ViewModel() {
  val quantidade = repo.itens.map { it.size }
    .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), 0)
}

@Composable
fun BadgeCarrinho(vm: CarrinhoViewModel) {
  val qtd by vm.quantidade.collectAsStateWithLifecycle()
  BadgedBox(badge = { if (qtd > 0) Badge { Text("$qtd") } }) { Icon(Icons.Default.ShoppingCart, null) }
}

WhileSubscribed e collectAsStateWithLifecycle param a coleta quando a tela some — sem vazamento e sem trabalho em segundo plano.

Em resumo

Referências

Continue aprendendo

Todos os temas de boas práticas e padrões →