# Arquitectura Android 2021
## Arquitectura
Desde hace varios años, el departamento Android basa el proyecto base con el que arrancar los proyectos nuevos en una arquitectura limpia siguiendo las directrices de Clean Architecture, dando soporte desde el SDK 21 (Android 5.0) hasta la nueva el SDK 30 (Android 11). Esta gran compatibilidad entre diferentes versiones es gracias al sustento por parte de Google con las bibliotecas de compatibilidad de AndroidX.
Esta arquitectura está basada en la separación de responsabilidades entre las 3 capas principales de la aplicación: Datos, Dominio y Presentación. Su razón de ser es la de hacer las aplicaciones que desarrollamos más robustas, escalables y mantenibles conforme estas crecen, sufren modificaciones o maduran en el tiempo.
Hasta la aparición de Android Jetpack, la capa de presentación estaba montada con el patrón Model-View-Presenter (MVP) pero ya desde entonces y usando los componentes proporcionados por Google el patrón utilizado es Model-View-ViewModel (MVVM).
Este patrón usa el protocolo Observador-Observable para la exposición de los datos a la capa de UI, intentando evitar que la vista gestione cambios de estados, delegando este propósito al ViewModel. La UI sólo se preocupa de renderizar ese estado actual del sistema proporcionado, escuchar las interacción del usuario y gestionar eventos del sistema.
Los ViewModel están compuestos por una serie de LiveData y funciones que dan acceso a estos para que puedan ser observados desde el Fragment o Activity. Estos LiveData se inicializan o cambian de valor tras ejecutar Casos de Uso.
En estos casos de uso es dónde se producen las lógicas de negocio tras cambios de estado, comunicación con el Repositorio de datos u otras labores complejas. Trabajan apoyados en las Corutinas y Flow de Kotlin. Con estos componentes podemos realizar las funcionalidades comentadas gracias a que se pueden realizar en hilos diferentes al principal, podemos bloquearlos con el patrón async-await para esperar a obtener datos o incluso mantener un flujo de datos activo en el que emitir diversos estados desde la misma ejecución del caso de uso. Además, dado que estos casos de uso son lanzados desde los ViewModel podemos asociar estas ejecuciones al ciclo de vida tanto de estos como al del Fragment o Activity, así pues, si estos dejan de tener sentido y se librean de memoria, las corutinas pendientes de ejecutar se liberan también.
Las funcionalidades que definen a nuestras aplicaciones están implementadas con este paradigma y para la navegación dentro de cada funcionalidad y entre diferentes funcionalides usamos la librería de Navegación, también de Jetpack.
En la capa de dominio se definen los objetos que modelan el negocio que cubre la aplicación, además de los repositorios de datos sobre los que se sustenta la misma.
Cada repositorio define las diferentes fuentes de datos con los que trabajará nuestra aplicación, así como decide que fuente de datos usa en cada momento dependiendo de las circunstancias. Estas fuentes de datos puedes ser servicios REST, caché de datos, bases de datos propias, preferencias o incluso archivos en la memoria del dispositivo.
Estas fuentes de datos definidas en la capa de dominio han de ser implementadas en la capa de datps, ya que requieren integraciones y configuraciones con librerías externas o componentes del SDK que no son conocidos por el negocio. Se definen además los modelos de datos de cada capa, ya sean entidades y el acceso de estas mediante DAOs para las bases de datos o bien los datos persistidos en preferencias, o los obtenidos mediante la serialización de los JSON proporcionados en los servicios de la api REST.
Toda esta arquitectura está distribuída en los diferentes módulos de los que se compone el proyecto de Android Studio, haciendo a cada uno de ellos fácilmente intercambiable o modificable, así evitamos compilaciones completas del proyecto con cada cambio.
Librerías usadas como parte fundamental de este ecosistema:
- Jetpack
- [AndroidX](https://developer.android.com/jetpack/androidx/)
- [Material Design](https://developer.android.com/guide/topics/ui/look-and-feel?hl=es_419)
- [RecyclerView](https://developer.android.com/guide/topics/ui/layout/recyclerview?hl=es_419)
- [Livedata]( https://developer.android.com/topic/libraries/architecture/livedata?hl=es)
- [ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel?hl=es)
- [Navigation](https://developer.android.com/guide/navigation?hl=es_419)
- [Room](https://developer.android.com/training/data-storage/room?hl=es)
- [DataStore](https://developer.android.com/topic/libraries/architecture/datastore?hl=es_419)
- Integración con APIs REST y serialización
- [OkHttp](https://square.github.io/okhttp/)
- [Retrofit](https://square.github.io/retrofit/)
- [Moshi](https://github.com/square/moshi/)
- Inyección de dependencias
- [Dagger Hilt](https://developer.android.com/training/dependency-injection/hilt-android)
Android
- Compose
- Flow