ViewModel¶
En anteriores temas cuando hablamos de la arquitectura de aplicaciones de Android ya mencionamos este componente como parte de la Capa de UI. En este tema vamos a centrarnos en él para concretar la implementación de MVVM en nuestra capa UI de la arquitectura.
ViewModel es una de esas clases que Google definió, allá por 2018, en la primera versión de Jetpack para ayudar a los desarrolladores a crear aplicaciones de Android más robustas y fáciles de mantener. ViewModel es una clase que está diseñada para almacenar y administrar datos relacionados con la interfaz de usuario de una manera que sobrevive a los cambios de configuración, como la rotación de la pantalla.
Los beneficios clave de la clase ViewModel son básicamente dos:
- Te permite conservar el estado de la IU.
- Proporciona acceso a la lógica empresarial, idealmente a través de casos de uso definidos en el dominio.
Alcance de un ViewModel (ViewModel Scope)¶
Cuando se crea una instancia de ViewModel, se pasa un objeto que implementa la interfaz ViewModelStoreOwner.
Los objetos que implementan ViewModelStoreOwner puede ser por ejemplo:
- Una
ActivityoComponentActivity. - Un
Fragment. - Un destino de Navigation
NavBackStackEntry.
A tener en cuenta
El alcance de tu ViewModel se define en el Ciclo de vida del ViewModelStoreOwner. Esto es, continúa en la memoria hasta que su ViewModelStoreOwner desaparece de forma permanente.
Cuando se destruye el fragmento o la actividad para los que se definió el alcance del ViewModel, el trabajo asíncrono continúa en el ViewModel específico. Esta es la clave de la persistencia.
Cuando se definió la clase ViewModel en la primera versión de Jetpack, aún no existia Compose y se usaba asociado a una vista como un Activity o a un Fragment. Nuestras aplicaciones de Android se componían de una o más Activity o Fragment y cada uno de ellos tenía su propio ViewModel que se creaba como una instancia única. ViewModel se usaba para almacenar datos que se necesitaban en la interfaz de usuario de la Activity/Fragment o el Fragment y queríamos que sobrevivieran a los cambios de configuración o queríamos compartir datos entre ellos.
Con la llegada de Jetpack Compose este enfoque ha cambiado y Google ahora recomienda aplicaciones de actividad única donde las diferentes pantallas se cargan como contenido dentro de la misma actividad. Por tanto, un ViewModel utilizado por una actividad permanece en memoria hasta que la actividad finalice esto es hasta que la aplicación finalice.
Ciclo de vida de un ViewModel¶
- En el caso de una
Activity, hasta que termina. (El más común) - En el caso de un
NavBackStackEntry, hasta volvemos atrás en el grafo.
En la imagen de la derecha vemos que el objeto ViewModel cuyo 'propietario' (el ViewModelStoreOwner) es una Activity que tiene un cambio de configuración (rotación de pantalla) y por tanto se destruye y vuelve a crearse su vista asociada.
-
Se crea al llamarse al método
onCreate()de laActivitysolo la primera vez y aunque se vuelva a llamar aonCreate()por un cambio de configuración, no se vuelve a crear permanece el mismo objetoViewModelque se creó en la primera llamada. -
No se destruye aunque la
Activitydestruya su vista y permanece en memoria hasta la finalización de laActivity, en ese momento se llama al métodoonCleared()delViewModelpara que realice las tareas de limpieza necesarias.
Prácticas no recomendadas¶
Las siguientes son varias prácticas recomendadas clave que debes seguir cuando implementes ViewModel:
-
NO definas
ViewModelpara composables reutilizables en tu UI o para componentes de IU que no sean de nivel superior. Deberíamos definirlos a nivel de Screen (pantalla). -
Los ViewModels NO deberían conocer los detalles de implementación de la IU. Mantén los nombres de los métodos que expone la API de ViewModel y los de los campos del UIState lo más genéricos posible.
-
Como pueden tener una vida más larga que el
ViewModelStoreOwner, los ViewModels NO deberían contener ninguna referencia de APIs relacionadas con el ciclo de vida, comoContextoResourcespara evitar fugas de memoria. -
NO pases ViewModels a funciones ni otros componentes de la IU. Esto evita que los componentes de nivel inferior accedan a más datos y lógica de los que necesitan.
-
Derivado del anterior NO instancies directamente un objeto ViewModels. En su lugar, usa algún tipo de 'proveedor de ViewModels' para obtener una instancia del mismo.
Actividad¶
-
AC 501. Toca hacer un poco de investigación para poner el modelo MVVM en contexto. Para ello, debes seleccionar tres arquitecturas de la siguiente lista
- Arquitectura monolítica
- Arquitectura cliente–servidor clásica
- MVC
- Arquitectura basada en servicios (SOA)
- Microservicios
- Serverless
- SPA (Single Page Applications)
- REST
- GraphQL
- ECS (Entity–Component–System) para videojuegos
- Arquitectura cliente–servidor multijugador en videojuegos
Redactar un texto que incluya, para cada arquitectura, además de la MVVM:
- Descripción general: en qué consiste y cómo se organiza.
- Tecnologías o frameworks habituales en web, móvil o videojuegos.
- Ventajas y desventajas principales.
- Casos de uso reales, indicando si se aplica mejor a web, móvil, videojuegos o varios.
Luego haz una comparación:
- Escalabilidad
- Rendimiento
- Complejidad
- Coste de mantenimiento
- Adecuación a proyectos web, móviles y videojuegos
- Facilidad para trabajar con APIs, backend y sincronización de datos
La entrega
Sé imaginativo… o no. Esta actividad puede entregarse en el formato que consideres más adecuado para transmitir tu mensaje: infografía, vídeo, documento de texto, presentación… sky is the limit 🚀!
