Elegir qué arquitectura para Android utilizar es un paso importante. Una vez entendemos la importancia de implementarlas, lo siguiente es ver qué opciones tenemos y en qué consisten cada una de ellas.
Para comenzar, vamos a ver unas breves definiciones sobre algunas palabras o conceptos clave para entender la descripción de las arquitecturas de software para Android.
Glosario
- Capa / Layer. En arquitecturas, se refiere a un componente principal. Es decir, un pilar que conforma una arquitectura. Es una sección que contempla un objetivo en particular. Por ejemplo, si habláramos de una tarta, sabemos que existen diferentes capas que la conforman y juntas hacen la tarta, pero cada capa tiene una consistencia e ingredientes diferentes. Lo mismo pasa aquí, una arquitectura tiene capas con diferentes objetivos y elementos.
- Repositorio / Repository. Es un concepto que promueve el separar la lógica del acceso a datos, de la vista. El repositorio es un centro para gestionar las llamadas a las fuentes de datos.
- Entidad / Entity. Las entidades son los modelos de datos, es decir, aquellas clases que definen un objeto.
- Lógica de negocio / Business layer. Se refiere al comportamiento de tu app, pero solo aquello que no está establecido dentro de los componentes de la plataforma. Es decir, que una lista pueda deslizarse en la pantalla es un comportamiento, pero es parte de su esencia y reaccionará así en cualquier otra app. Las reglas de negocio serían comportamientos del tipo "muestra solo 10 elementos en la lista, y pagina el resto". Esa decisión es tuya, en favor de tu objetivo particular. Cada decisión que muestre un dato de cierta manera o que limite al usuario en cierto sentido, todo ello se clasifica como reglas de negocio.
- Casos de uso / Use cases. Son los que establecen qué acciones tomará un actor. Entiéndase actor como el usuario o entidad que influya en qué datos van a procesarse o mostrarse en una app. Ejemplo: en un inicio de sesión, los casos de uso serían, iniciar sesión, ir a registrarse, recuperar contraseña, etc. Todas las posibles acciones son casos de uso.
- Dominio / Domain. Es el apartado que almacena las reglas de negocio, entidades y casos de uso. No necesariamente es una capa, solo algunas arquitecturas proponen a Domain como tal.
- Modelo / Model. Comúnmente usado para nombrar a la capa asignada a los datos de una app, bases de datos, consultas, etc. Posiblemente es la capa más repetida, junto a la vista.
- Vista / View. Como su nombre indica, es la Vista, y se refiere a la parte gráfica, la parte visible que el usuario puede ver, y muchas veces interactuar con ella. Suele ser una capa principal.
- Dependencias-Inyección. Una dependencia se da cuando una clase necesita de otra para funcionar. Podemos ver eso muy a menudo por ejemplo cuando usas una librería, digamos una base de datos. En alguna parte del código tenemos que instanciar la base de datos en una variable. Eso hace que nuestra clase tenga esa dependencia. Ahora, la inyección de dependencias es implementar un sistema dónde no tengamos que instanciar las clases de las cuales dependemos. ¿Cómo? Bueno, por medio de instancias independientes, públicas, que serán inyectadas. Es decir, proveídas, siempre que se requieran. En otras palabras, es delegar esa responsabilidad a un factor externo a la clase.
- Módulo / Module. Es el resultado de implementar una arquitectura. Visto desde un punto de vista individual, la idea es separar el código a modo que cada módulo contenga solo las clases que tengan que ver con unos casos de uso relacionados para un fin mayor. Otra forma común y fácil de ver el alcance de un módulo, es tener claro que cada vista es un módulo. Ejemplos de esto son la pantalla de inicio de sesión = módulo login, perfil de usuario = módulo perfil, listado principal= módulo principal, pantalla para ver favoritos = módulo favoritos, etc. Cada módulo debería necesitar solo de sí mismo y de elementos comunes como la base de datos o entidades, al punto de que si quisiéramos, pudiéramos extraerlo y crear una mini app por cada módulo.
¿Qué debe tener una arquitectura para android, según Google?
Como es bien sabido, Android es una plataforma cuyo principal soporte viene de Google, ya que este es quien desarrolla el sistema operativo base. Por esa razón, si queremos saber qué elementos tomar en cuenta, debemos escuchar principalmente al fabricante.
Los puntos esenciales que hacen a una arquitectura para Android una buena elección, son:
- Uso de repositorios que gestionen los datos de la app
- El uso de ViewModel con LiveData para sobreponerse al ciclo de vida
- Cambio de interfaz por medio de elementos reactivos, reduciendo la lógica de la vista
De forma adicional, hay otros elementos que si bien son opcionales, son altamente recomendados, por ejemplo:
- Inyección de dependencias, para modular e independizar las clases, asegurando su consistencia
- Capa de dominio, fomentando la separación y el reciclaje de código enfocado en las reglas de negocio. Es decir, la lógica propia de nuestros requerimientos
- SRP. Principio de responsabilidad única, que nos impulsa a tener clases más simples
- Modularidad. La separación de vistas o servicios para que funcionen lo mas independientemente posible, como si cada módulo fuera una mini app por separado
- Ser escalable. Una buena arquitectura debe permanecer intacta sin importar si es una app pequeña, o un proyecto gigante en constante crecimiento
- Legibilidad. Dicen los grandes programadores, que la mejor documentación de código, es la que menos comentarios requiere
Consejo: Existen más elementos que pueden ser tomados en cuenta. Tú eres libre de implementar más conceptos, patrones o principios que enriquezcan tu arquitectura para Android. Solo asegúrate de que no rompa nada de lo anteriormente implementado.
¿Qué arquitecturas aprender? ¿Y por qué?
Veamos rápidamente las arquitecturas más solicitadas a desarrolladores Android. Y veamos también cuales son las más viables. Tengamos en cuenta que algunas ofertas de trabajo las hacen personas sin conocimientos especializados.
Nota: MVC: Model View Controller, el modelo se encarga del acceso a datos. Controlador es el centro de distribución que comunica y gestiona las respuestas de la vista y modelo. Vista es la interfaz donde interactúa el usuario. El problema es que en Android, las actividades son 2 en uno, es decir, son controladores y a su vez necesitan inflar la vista para funcionar. Por esta razón, si bien se pueden encontrar proyectos que usen MVC, no es recomendable porque nunca se respetará su origen.
MVP
Model View Presenter. Lo curioso es que justamente MVP es la adaptación de MVC, pero para Android. Tiene la peculiaridad de centralizar la lógica en la capa del presententador. Aquí se promueve que la vista no tenga lógica, que se limite a reaccionar al usuario, o al presentador, y por otro lado, el modelo gestiona los datos para dar respuesta a las solicitudes que le haga el presentador. Fue muy popular con Java, pero desde Kotlin se quedó en el olvido, ¿por qué?
MVVM
Model View ViewModel. Con la llegada de Kotlin, Jetpack y AndroidX, se vino una revolución de nuevos elementos impulsados por Google para formar una arquitectura para Android definitiva. Así nace MVVM.
A simple vista, esta arquitectura puede verse similar a MVP, pero con un una gran diferencia: aquí se soluciona el principio de aplicaciones reactivas. ¿Qué significa eso? Básicamente que la vista y ciertos flujos de código, deben simplemente reaccionar a cambios de datos o estados. El nombre de esta solución es DataBinding.
Modelo sigue teniendo el mismo concepto, pero ahora que tenemos una View reactiva, falta saber qué es ViewModel, dónde esta capa trae otro par de complementos vitales: LiveData para generar variables observables, y una separación del ciclo de vida.
Si quieres hacer una apuesta segura, empieza por aquí, MVVM es hoy por hoy la arquitectura que todo programador Android debe saber para buscar y conseguir un buen empleo.
MVI
Model View Intent. Una nueva propuesta que ha tenido sus fans, donde el modelo se conserva prácticamente igual que en cualquier arquitectura. Vista se reinventa para ser reactiva, pero sin la necesidad de usar DataBinding o LiveData. Para ello observa estados.
Se recomienda el uso de ViewModel y se presenta un nuevo concepto (Intención). La capa de Intención se refiere a definir las acciones (a esto nos referimos con intenciones), de nuestro usuario. En otras palabras, sus casos de uso.
Con esta arquitectura también llega otro concepto peculiar, la unidirección. Es decir, que exista un solo camino para funcionar, view>intent>viewModel>model>viewModel>state>view.
Clean
Clean Architecture es sumamente popular, pero hay que dejar algo muy en claro: más que una arquitectura para Android, es un concepto, una guía, dónde se propone tener 3 capas básicas, Domain, Data, y Presentation.
Como dije, es un concepto, una serie de principios que pueden implementarse en arquitecturas como las antes mencionadas. Bien podríamos presumir tener un proyecto con la arquitectura limpia, y al mismo tiempo abrir el proyecto y de entrada ver MVI por ejemplo.
Entonces, ¿qué hace que un proyecto tenga la arquitectura limpia? Bueno, básicamente que cumpla con estos principios: Solo la vista y sus conexiones directas pueden tener el SDK de Android. Es decir, no lanzar un fragment desde el model. En otras palabras, aislar lo propio de Android lo más posible para que el resto de capas se centren en el uso de Kotlin lo máximo posible. Aquí podríamos colocar a los presentadores, viewModels y similares.
Datos es el puente entre la capa del dominio y lo referente a la vista. La clase más representativa sería el repositorio. Y dominio sería un nivel central que guarda las reglas de negocio, las entidades y la abstracción de las otras capas. Este es el punto central de tu proyecto.
También podemos visualizar más claramente el concepto así. Capa nuclear (dominio), capa intermedia (Datos), capa exterior (Presentación).
Las dependencias van de fuera hacia dentro. Es decir, la capa nuclear en su última instancia, debe ser libre de dependencias. Conforme salimos del esquema, es fácil ver como el resto de capas sí dependen del siguiente nivel para funcionar. Podemos ver el flujo de trabajo atravesar las distintas capas.
Recomended Architecture
Como ya mencionamos anteriormente, Google desarrolla Android. ¿Qué mejor opinión podemos escuchar, que la del mismo fabricante? Así que, según el equipo oficial de Android, lo mejor es usar MVVM como base, pero adicionalmente complementarla con librerías y principios que sean compatibles y que nos den como resultado una arquitectura más completa y sólida.
A esta arquitectura la han llamado la arquitectura recomendada, sin más. No se rompieron la cabeza para nombrarla. Al final de nuestro curso, desde luego veremos esta arquitectura, pues de momento es lo más moderno y completo que existe para desarrollar aplicaciones Android.
A nivel de capas, aquí se propone una nueva (Dominio). Esta capa se encargará de centralizar la lógica de las reglas de negocio. Comúnmente se ve como sub-capa de Modelo, pero también puede implementarse a nivel Vista, concretamente con adaptadores de DataBinding.
La ventaja de esta arquitectura para Android es que las librerías son creadas en su gran mayoría por el mismo Google, por lo que siempre serán compatibles y nos darán soluciones elegantes a problemas complejos, como lo puede ser Room, LiveData, Navigation, ViewModel, DataBinding, Hilt, solo por mencionar algunas.
Lo mejor de esta arquitectura es que las librerías se hacen pensando en que se respeten los patrones de diseño y los principios recomendados. Aunque requiere mas tiempo para dominarla, vale la pena porque definitivamente estaremos seguros de que nuestro software será de calidad global.
Entonces ¿Qué arquitectura debería elegir?
Hay una gran variedad de arquitecturas disponibles. algunos nombres populares son MVC, MVP, MVVM, Clean, etcétera. Algunas incluso no tienen nombre, pues son propuestas independientes. Algunas vienen de otras plataformas, pero como son populares, muchos las piden.
Al inicio siempre es incierto elegir una arquitectura para Android. Todo el mundo quisiera la más robusta, pero también suele ser la más difícil, y luego nos preguntamos, ¿necesitare tanto? Quizá con menos mi proyecto tenga éxito de todas formas.
Esto se parece más a una comida o cena en un restaurante tipo Buffet. Tantas opciones disponibles, pero para hacer una buena decisión en el Buffet, primero debemos conocer nuestros gustos, ¿cierto?
Bueno, pues aquí es similar. Solo que en lugar de gustos, tenemos necesidades. Si logramos traducir nuestras necesidades humanas en requerimientos técnicos, la elección es fácil.
Tanta variedad de opciones pueden ser abrumadora. Tratar de aprender todas las arquitecturas para estar seguros de elegir bien puede ser un verdadero reto al principio.
La buena noticia, es que si se cumplen los puntos básicos de una buena arquitectura, cualquiera puede ser viable. Además de que podemos combinar y tener una arquitectura propia que se ajuste a nuestras necesidades particulares.
Y como punto final, decir que no tienes por qué tomar la mejor decisión ahora mismo. Puedes empezar por una arquitectura básica y luego migrar tu proyecto a una más completa. Yo lo he hecho muchas veces y te aseguro que siempre se puede adaptar tu lógica a patrones y estructuras nuevas.
En síntesis, no te rompas la cabeza al inicio. Aprende las más populares y luego usa la que menos problemas te genere al implementarla. Con el tiempo intenta implementar más elementos avanzados en tu arquitectura para Android.
Si te interesa saber más sobre el origen, significado, ventajas y desventajas de las arquitecturas, te recomiendo los siguientes artículos: ¿Son necesarias las arquitecturas de software? y ¿Qué arquitecturas para Android hay? Ventajas y desventajas
Y si deseas aprender a implementar las arquitecturas más importantes para Android con Kotlin, puedes hacerlo en el siguiente enlace: Curso Arquitecturas para Android
Déjanos en los comentarios si ya has implementado alguna, o qué arquitectura para Android has elegido para tus proyectos futuros.
Fuerte abrazo!
Ing. Alain Nicolás Tello.
Cursos ANT.