A Arquitetura do Android Está Silenciosamente Avançando além de ViewModel como Guarda de Estado
Compose não substituiu o ViewModel. A Navegação 3 também não o fez. Juntos, eles estão redesenhando onde a estado pertence.
Há anos, os desenvolvedores do Android seguiram uma única regra simples:
Coloque o estado da tela em um ViewModel.
Não era apenas uma boa dica, tornou-se uma das bases da arquitetura do Android.
- Valores de TextField
- Abas selecionadas
- Visibilidade de diálogo
- Posição de rolagem
- Argumentos de navegação
- Lógica de negócios
Eventualmente, os ViewModels se tornaram responsáveis por quase tudo.
ViewModel
├── Estado da UI
├── Estado de Navegação
├── Lógica de Negócios
├── Coordenação do Repositório
└── Escopo de CoroutinesEssa arquitetura resolveu problemas reais.
ViewModel sobreviveu às mudanças de configuração.
SavedStateHandle restaurou o estado após a morte do processo.
Activities e Fragments ficaram muito menores.
Para o sistema de Views, foi a solução certa.
Mas a arquitetura do Android evoluiu silenciosamente.
Não removendo ViewModel.
Dando a cada tipo de estado um proprietário mais adequado.
Compose Mudou a Questão
Uma das maiores mudanças arquiteturais introduzidas pelo Compose não foi uma nova API.
Mas era uma nova pergunta.
Em vez de perguntar:
Onde devo colocar esse estado?
Compose nos encoraja a perguntar:
Quem naturalmente possui esse estado?
A orientação oficial diz:
Você deve manter o estado mais próximo do local onde ele é consumido.
Essa única frase representa uma mudança significativa.
Por anos, desenvolvedores frequentemente moviam todos os valores de UI para um ViewModel.
Compose diz algo diferente.
Mantenha o estado onde ele naturalmente pertence.
Só mova-o mais alto quando outra camada realmente precisa dele.
Não Todo Estado Precisa de Um ViewModel
Compose torna isso óbvio com remember.
var query by remember {
mutableStateOf("")
}Quando o valor deve sobreviver à recriação da Activity, Compose fornece rememberSaveable.
var query by rememberSaveable {
mutableStateOf("")
}- Pesquisas de busca
- Abas selecionadas
- Cards expandidos
- Visibilidade de diálogo
- Posição de rolagem
Esses são preocupações da UI.
Não são lógica de negócios.
Mantê-los dentro da UI melhora a localidade porque o estado vive exatamente onde é usado.
Agora, O Google Não Trata ViewModel Como o Único Guardião do Estado
Essa mudança arquitetônica também aparece na orientação oficial.
Mas em vez de descrever ViewModel como o lugar universal para estado da interface do usuário, agora o Android introduz a noção mais ampla de mantenedores de estado.
A documentação explica:
Você pode implementar um mantenedor de estado através de uma ViewModel ou de uma classe simples.
Essa é uma distinção importante.
Um ViewModel é uma implementação de um mantenedor de estado.
Agora, isso não define mais o conceito.
O guia também separa os mantenedores de estado em duas categorias:
- Mantenedores de estado para lógica empresarial
- Mantenedores de estado para lógica da interface do usuário
Essa separação reflete um modelo de propriedade muito mais preciso.
ViewModel é um Mantenedor de Estado para Lógica Empresarial
A documentação oficial descreve explicitamente ViewModel como um mantenedor de estado para lógica empresarial.
Suas responsabilidades incluem:
- coordenar repositórios
- preparar dados para apresentação
- expor o estado da interface do usuário
- sobreviver à recuperação de Activity
- integrar com Navegação
Note o que está ausente.
- valores de TextField
- visibilidade de diálogo
- abas selecionadas
Eles são estados de elementos da interface do usuário.
A documentação até menciona que componentes de interface do usuário reutilizáveis geralmente devem usar mantenedores simples de estado da interface do usuário em vez de ViewModels.
Navegação 3 Completa a Separação
A Navegação 3 continua exatamente na mesma direção.
Os argumentos de navegação pertencem a NavKey.
data class UserDetail( val userId: Long ) : NavKey
O estado da IU pode pertencer ao destino em si através de rememberSerializable.
var query by rememberSerializable {
mutableStateOf("")
}Em vez de pedir ao ViewModel para lembrar tudo, cada entrada de navegação possui o estado que pertence a essa entrada.
A responsabilidade se torna muito mais clara.
Estado da IU ↓ remember rememberSaveable rememberSerializable Estado de Navegação ↓ NavKey Lógica de Apresentação ↓ ViewModel Dados Persistentes ↓ Repository
A versão 3 da navegação não substitui o ViewModel.
Ela remove mais uma responsabilidade que nunca pertenceu naturalmente lá.
O ViewModel está se tornando um produtor de estado
Considere um ViewModel típico.
val uiState = combine(
usersRepository.users,
settingsRepository.settings
) { users, settings ->
HomeUiState(
users = users,
darkMode = settings.darkMode
)
}.stateIn(…)Onde está a verdadeira fonte?
Não dentro do ViewModel.
Os repositórios já possuem os dados.
O ViewModel transforma esses fluxos em algo que a IU pode exibir.
Mais do que ser um contêiner de estado mutável, o ViewModel está se tornando cada vez mais um produtor de estado da UI.
É uma mudança sutil - mas importante.
A arquitetura fica mais simples
O guia oficial de arquitetura resume a ideia com uma recomendação simples:
Hold state as low as possible while maintaining proper ownership.
Essa frase captura a direção da arquitetura moderna do Android.
Composto
└── Estado da IU
Navegação
└── Estado de Navegação
ViewModel
└── Lógica de Apresentação
Repositório
└── Dados PersistentesCada camada possui o estado que entende melhor.
Nada se sobrepõe.
Nada existe apenas porque “é onde sempre colocamos”.
E quanto às Mudanças de Configuração e à Morte do Processo?
Mover o estado da IU fora de ViewModel não significa abandonar a resiliência.
Pelo contrário.
Quando cada camada usa o mecanismo projetado para sua vida útil, seu aplicativo ainda pode sobreviver tanto a mudanças de configuração quanto à morte do processo.
Estado da IU
├── rememberSaveable
└── rememberSerializable
Navegação
└── NavKey
Dados Persistentes
└── RepositórioO objetivo não é eliminar a persistência de estado.
O objetivo é parar de usar ViewModel como proprietário padrão para todo tipo de estado.
Conclusão
Compose não tornou ViewModel obsoleto.
A Navegação 3 também não o substituiu.
Em vez disso, ambas as bibliotecas estão gradualmente separando responsabilidades.
O estado da IU pertence à IU.
O estado de navegação pertence à Navegação.
Os dados persistentes pertencem aos repositórios.
A lógica de apresentação pertence ao ViewModel.
Talvez a maior mudança na arquitetura do Android não seja uma nova API.
É uma nova pergunta.
Ao invés de perguntar:
Como devo armazenar esse estado em meu ViewModel?
devemos perguntar:
Quem naturalmente possui este estado?
Essa pequena mudança de perspectiva leva a uma arquitetura muito mais simples.
E está alinhada de perto com a direção que as próprias orientações arquiteturais da Google têm se movido nos últimos anos.

