Guía sobre la modularización de apps para Android

Gradle ofrece la posibilidad de crear proyectos de varios módulos. En esta guía, se incluyen las prácticas y los patrones recomendados para desarrollar apps para Android con varios módulos.

El problema de la base de código creciente

En una base de código en constante crecimiento, la escalabilidad, la legibilidad y la calidad general del código suelen disminuir con el tiempo. Esto se debe a que el tamaño de la base de código aumenta sin que los encargados de su mantenimiento tomen medidas activas para aplicar una estructura que se pueda mantener fácilmente. La modularización es una forma de estructurar la base de código de una manera que mejore el mantenimiento y ayude a evitar estos problemas.

¿Qué es la modularización?

La modularización es una práctica para organizar una base de código en partes con acoplamiento bajo y elementos independientes. Cada parte es un módulo. Cada módulo es independiente y tiene un propósito claro. Si divides un problema en subproblemas más pequeños y fáciles de resolver, se reduce la complejidad de diseñar y mantener un sistema grande.

Figura 1: Gráfico de dependencia de un ejemplo de base de código de varios módulos.

Beneficios de la modularización

Los beneficios de la modularización son muchos, aunque cada uno se centra en mejorar la capacidad de mantenimiento y la calidad general de una base de código. En la siguiente tabla, se resumen los beneficios clave.

Beneficio Resumen
Capacidad de reutilización La modularización ofrece oportunidades para compartir código y compilar varias apps desde la misma base. Los módulos son componentes fundamentales. Una app deben ser una suma de sus funciones cuando estas se organizan como módulos separados. La funcionalidad que proporciona un módulo determinado puede o no estar habilitada en una app en particular. Por ejemplo, un :feature:news puede ser parte de la versión final y la app de Wear, pero no de la versión de demostración.
Control de visibilidad estricto Los módulos te permiten controlar fácilmente lo que expones a otras partes de tu base de código. Puedes marcar todo excepto la interfaz pública como internal o private para evitar que se use fuera del módulo.
Entrega personalizable Play Feature Delivery usa las funciones avanzadas de los paquetes de aplicaciones, lo que te permite ofrecer ciertas funciones de tu app de manera condicional o a pedido.

Los beneficios anteriores solo se logran con una base de código modular. Los siguientes beneficios se pueden lograr con otras técnicas, pero la modularización puede ayudarte a aplicarlos aún más.

Beneficio Resumen
Escalabilidad En una base de código de acoplamiento alto, un solo cambio puede desencadenar una cascada de alteraciones en partes de código aparentemente no relacionadas. Un proyecto modularizado adecuadamente adoptará el principio de separación de problemas y, por lo tanto, limitará el acoplamiento. De esta manera, los colaboradores tendrán mayor autonomía.
Propiedad Además de habilitar la autonomía, los módulos también se pueden usar para aplicar la responsabilidad. Un módulo puede tener un propietario dedicado que sea responsable de mantener el código, corregir errores, agregar pruebas y revisar los cambios.
Encapsulamiento El encapsulamiento significa que cada parte de tu código debería tener el menor conocimiento posible sobre otras partes. El código aislado es más fácil de leer y entender.
Capacidad de realizar pruebas La capacidad de realizar pruebas determina qué tan fácil es probar tu código. Un código que se puede probar es aquel en el que los componentes se pueden probar fácilmente de forma aislada.
Tiempo de compilación Algunas funcionalidades de Gradle, como la compilación incremental, la caché de compilación o la compilación en paralelo, pueden aprovechar la modularidad para mejorar el rendimiento de la compilación.

Errores comunes

El nivel de detalle de tu base de código es la medida en la que está compuesta por módulos. Una base de código más detallada tiene más módulos de menor tamaño. Cuando diseñas una base de código modular, debes decidir un nivel de detalle. Para hacerlo, ten en cuenta el tamaño de la base de código y su complejidad relativa. Usar un nivel de detalle demasiado alto hará que la sobrecarga se convierta en un problema, y hacerlo demasiado general reducirá los beneficios de la modularización.

Estos son algunos de los errores más comunes:

  • Muy detallada: Cada módulo genera cierta sobrecarga en forma de mayor complejidad de compilación y código estándar. Una configuración de compilación compleja dificulta la consistencia de las configuraciones entre los módulos. El exceso de código estándar da como resultado una base de código engorrosa que es difícil de mantener. Si la sobrecarga contrarresta las mejoras de escalabilidad, deberías considerar consolidar algunos módulos.
  • Demasiado detallado: Por el contrario, si los módulos son demasiado grandes, es posible que obtengas otra aplicación monolítica y pierdas los beneficios que ofrece la modularidad. Por ejemplo, en un proyecto pequeño, está bien colocar la capa de datos dentro de un solo módulo. Pero a medida que crece, puede ser necesario separar los repositorios y las fuentes de datos en módulos independientes.
  • Demasiado complejo: No siempre tiene sentido modularizar tu proyecto. Un factor dominante es el tamaño de la base de código. Si no esperas que tu proyecto crezca más allá de un cierto límite, no se aplicarán las ganancias de escalabilidad ni de tiempo de compilación.

¿La técnica de modularización es adecuada para mí?

Si necesitas los beneficios de la reutilización, un control de visibilidad estricto o usar Play Feature Delivery, la modularización es necesaria para ti. Si no los necesitas, pero aún deseas beneficiarte de una mejor escalabilidad, propiedad, encapsulamiento o tiempos de compilación, vale la pena considerar la modularización.

Ejemplos