
¿Qué encontrarás en este artículo?
En 2016, comencé a aprender Java y, a principios de 2017, Android. Desde el principio, ya sabía que había un concepto de arquitectura de aplicación, pero no sabía cómo aplicarlo en mi código. Encontré muchas guías diferentes, pero esto no fue más claro.
Este artículo es exactamente el que me gustaría leer al comienzo de mi viaje.
La importancia de la arquitectura de aplicaciones
Muchas compañías realizan pruebas técnicas para los candidatos que están siendo seleccionados. Las pruebas pueden variar, pero hay una cosa que las une. Todos ellos requieren comprensión y la capacidad de utilizar una buena arquitectura de software.
La buena arquitectura de software facilita la comprensión, el desarrollo, el mantenimiento y la implementación del sistema [Libro "Arquitectura limpia", capítulo 15]
El propósito de este artículo es enseñar a alguien que nunca ha usado la arquitectura a desarrollar aplicaciones de Android para hacer esto. Para hacer esto, consideraremos un ejemplo práctico de una aplicación, al crear la cual implementamos la solución menos flexible y una solución más óptima usando arquitectura.
Ejemplo
Elementos en un RecyclerView:

- Recibiremos datos de la API y mostraremos los resultados al usuario.
- El resultado será una lista de cervezas con un nombre, descripción, imagen y contenido de alcohol para cada una.
- La cerveza debe ordenarse por grado de fortaleza.
Para resolver este problema:
- Necesitamos obtener datos de la API.
- Ordenar elementos desde el grado más bajo al más alto de la fortaleza.
- Si el contenido de alcohol es inferior al 5%, se dibujará un círculo verde, si está entre 5% y 8%, el círculo será naranja y superior al 8%, un círculo rojo.
- Finalmente, necesitamos mostrar una lista de artículos.
¿Cuál es la solución menos flexible?
La solución menos flexible es crear una clase que cumpla con los cuatro puntos anteriores. Esta es la decisión que cualquiera de nosotros tomaría si no supiéramos cuál es la arquitectura de las aplicaciones.
El resultado para el usuario será aceptable: verá una lista ordenada en la pantalla. Pero si necesitamos escalar este sistema, entenderemos que la estructura no es fácil de entender, desarrollar, mantener e implementar.
¿Cómo entender la arquitectura de las aplicaciones en Android?
Daré un ejemplo muy simple. Imagine una fábrica de automóviles con cinco zonas:
- La primera zona crea el chasis.
- La segunda zona conecta las partes mecánicas.
- La tercera zona recoge un circuito electrónico.
- La cuarta área es la pintura.
- Y la última área agrega detalles estéticos.
Esto significa que cada zona tiene su propia responsabilidad, y trabajan en una cadena desde la primera zona hasta la quinta para lograr un resultado.
Tal sistema tiene una ventaja definitiva. Si el automóvil da un error después de que está terminado, entonces, dependiendo de su comportamiento, sabremos qué departamento debe solucionarlo sin molestar a los demás.
Si queremos agregar más detalles estéticos, pasaremos directamente a la quinta sección. Y si queremos cambiar el color, pasamos al cuarto. Y si cambiamos el chasis, esto no cambiará la forma en que funciona el área de pintura. Es decir, podemos modificar nuestra máquina puntualmente sin molestar a toda la fábrica.
Además, si con el tiempo deseamos abrir una segunda fábrica para crear un nuevo modelo de automóvil, será más fácil dividir las áreas de trabajo.
Arquitectura de aplicaciones de Android
Vamos a asegurarnos de que no haya una clase que haga todo el trabajo solo: solicitar datos de la API, ordenarlos y mostrarlos. Todo esto se distribuirá en varias áreas llamadas capas.
¿Qué son estas capas?

Para este ejemplo, vamos a crear una arquitectura limpia, que consta de tres niveles, que a su vez se dividirán en cinco:
- Nivel de presentación
- El nivel de la lógica empresarial.
- Y el nivel de datos.
1. Nivel de presentación
El nivel de presentación es el nivel de usuario, una interfaz gráfica que captura los eventos del usuario y le muestra los resultados. También verifica que no haya errores de formato en los datos ingresados por el usuario, y que los datos mostrados se muestren correctamente.
En nuestro ejemplo, estas operaciones se dividen entre la capa de interfaz de usuario y el nivel ViewModel:
- La capa de interfaz de usuario contiene Actividad y fragmentos que capturan eventos de usuario y muestran datos.
- La capa ViewModel formatea los datos para que la interfaz de usuario los muestre de una manera específica.
En lugar de usar ViewModel, podemos usar otra capa que realice esta función, es simplemente importante comprender las responsabilidades de cada capa.
En nuestro ejemplo, la capa de interfaz de usuario muestra una lista de cervezas, y la capa ViewModel informa de un color que debe usar dependiendo del rango de alcohol.
2. El nivel de lógica empresarial
En este nivel se encuentran todos los requisitos comerciales que debe cumplir la aplicación. Para esto, las operaciones necesarias se realizan aquí. En nuestro ejemplo, esta es la clasificación de cervezas de menor a mayor intensidad.
3. Capa de datos
En este nivel están los datos y la forma de acceder a ellos.
Estas operaciones se dividen entre el nivel de repositorio y el nivel de origen de datos:
- La capa de repositorio implementa la lógica de acceso a datos. Su responsabilidad es obtener datos. Es necesario verificar dónde buscarlos en un momento determinado. Por ejemplo, primero puede verificar la base de datos local y, si no hay datos allí, realizar una solicitud a la API y guardar los datos en la base de datos. Es decir, determina la forma de acceder a los datos. En nuestro ejemplo, solicita datos de cerveza directamente del nivel que interactúa con la API.
- La capa de origen de datos es directamente responsable de recibir los datos. En nuestro ejemplo, implementa la lógica de acceso API para obtener datos de cerveza.
¿Cómo interactúan las capas?
Veamos los enfoques teóricos y prácticos de la interacción.
En teoría:

Cada capa debe comunicarse solo con sus vecinos inmediatos. En este caso, si miramos el diagrama de arquitectura de software:
- La interfaz de usuario solo puede comunicarse con ViewModel.
- ViewModel solo puede comunicarse con el nivel de lógica empresarial.
- El nivel de lógica de negocios solo puede comunicarse con el nivel de repositorio.
- Y el repositorio solo puede comunicarse con la fuente de datos.
En la práctica:
Estructura del paquete en Android Studio IDE con una arquitectura limpia:

Tenemos una estructura de paquete en la que se crean las clases, cada una de las cuales tiene su propia área de responsabilidad.
Observaciones finales sobre la arquitectura de la aplicación
Vimos que cada nivel de arquitectura de software tiene su propia área de responsabilidad y todos están interconectados.
Es importante destacar que nunca hemos hablado sobre las bibliotecas o los lenguajes de programación utilizados, ya que la arquitectura se centra en la estructuración correcta del código para que sea escalable. Las bibliotecas cambian con el tiempo, pero los principios de la arquitectura permanecen.
Además, se recomienda leer sobre la inyección de dependencia para evitar crear instancias de objetos directamente en clases de arquitectura y, por lo tanto, para poder realizar pruebas unitarias utilizando Mockito y JUnit.
Estoy compartiendo un repositorio donde puedes ver:
- Un ejemplo de arquitectura limpia de Android con Kotlin.
- Use LiveData para conectar la interfaz de usuario con ViewModel.
- El uso de la corutina.
- Kodein para inyección de dependencia.
- JUnit y Mockito para probar la lógica empresarial.