Saltar al contenido principal

Recomendaciones y recursos de arquitectura

Recomendaciones para crear aplicaciones de Flutter escalables.

Esta página presenta las mejores prácticas de arquitectura, por qué son importantes y si las recomendamos para tu aplicación de Flutter. Deberías tratar estas recomendaciones como tales, y no como reglas inamovibles, y deberías adaptarlas a los requisitos únicos de tu app.

Las mejores prácticas en esta página tienen una prioridad, la cual refleja con qué fuerza las recomienda el equipo de Flutter.

  • Muy recomendado: Siempre deberías implementar esta recomendación si estás empezando a compilar una nueva aplicación. Deberías considerar seriamente refactorizar una app existente para implementar esta práctica a menos que hacerlo choque fundamentalmente con tu enfoque actual.
  • Recomendado: Es probable que esta práctica mejore tu app.
  • Condicional: Esta práctica puede mejorar tu app en ciertas circunstancias.

Separación de conceptos

#

Deberías separar tu app en una capa de UI y una capa de datos. Dentro de esas capas, deberías separar aún más la lógica en clases por responsabilidad.

RecomendaciónDescripción
Use clearly defined data and UI layers.
Muy recomendado

La separación de conceptos (separation of concerns) es el principio arquitectónico más importante. La capa de datos expone los datos de la aplicación al resto de la app, y contiene la mayor parte de la lógica de negocio de tu aplicación. La capa de UI muestra los datos de la aplicación y escucha los eventos de los usuarios. La capa de UI contiene clases separadas para la lógica de UI y los widgets.

Use the repository pattern in the data layer.
Muy recomendado

El patrón de repositorio es un patrón de diseño de software que aísla la lógica de acceso a datos del resto de la aplicación. Crea una capa de abstracción entre la lógica de negocio de la aplicación y los mecanismos de almacenamiento de datos subyentes (bases de datos, APIs, sistemas de archivos, etc.). En la práctica, esto significa crear clases Repository y clases Service.

Use ViewModels and Views in the UI layer. (MVVM)
Muy recomendado

La separación de conceptos es el principio arquitectónico más importante. Esta separación particular hace que tu código sea mucho menos propenso a errores porque tus widgets se mantienen "simples" (dumb).

Use ChangeNotifiers and Listenables to handle widget updates.
Condicional

La API ChangeNotifier es parte del SDK de Flutter, y es una forma conveniente de hacer que tus widgets observen los cambios en tus ViewModels.

Hay muchas opciones para manejar el State Management, y al final la decisión se reduce a una preferencia personal. Lee sobre nuestra recomendación de ChangeNotifier o otras opciones populares.

Do not put logic in widgets.
Muy recomendado

La lógica debe estar encapsulada en métodos en el ViewModel. La única lógica que debe contener una vista es:

  • Sentencias if simples para mostrar y ocultar widgets basados en una bandera o campo anulable en el ViewModel
  • Lógica de animación que depende del widget para calcular
  • Lógica de diseño (layout) basada en la información del dispositivo, como el tamaño de la pantalla o la orientación.
  • Lógica de enrutamiento simple
Use a domain layer.
Condicional

Una capa de dominio solo es necesaria si tu aplicación tiene una lógica extremadamente compleja que satura tus ViewModels, o si te encuentras repitiendo lógica en tus ViewModels. En apps muy grandes, los casos de uso son útiles, pero en la mayoría de las apps añaden una sobrecarga innecesaria.

Úsalo en apps con requisitos de lógica complejos.

Manejo de datos

#

Manejar los datos con cuidado hace que tu código sea más fácil de entender, menos propenso a errores y evita que se creen datos mal formados o inesperados.

RecomendaciónDescripción
Use unidirectional data flow.
Muy recomendado

Las actualizaciones de datos solo deben fluir desde la capa de datos a la capa de UI. Las interacciones en la capa de UI se envían a la capa de datos, donde se procesan.

Use Commands to handle events from user interaction.
Recomendado

Los comandos evitan errores de renderizado en tu app y estandarizan cómo la capa de UI envía eventos a la capa de datos. Lee sobre los comandos en el caso de estudio de arquitectura.

Use immutable data models.
Muy recomendado

Los datos inmutables son cruciales para garantizar que cualquier cambio necesario ocurra solo en el lugar adecuado, generalmente en la capa de datos o de dominio. Debido a que los objetos inmutables no se pueden modificar después de su creación, debes crear una nueva instancia para reflejar los cambios. Este proceso evita actualizaciones accidentales en la capa de UI y soporta un flujo de datos claro y unidireccional.

Use freezed or built_value to generate immutable data models.
Recomendado

Puedes usar paquetes para ayudar a generar funcionalidades útiles en tus modelos de datos, como freezed o built_value. Estos pueden generar métodos de modelo comunes como serialización/deserialización JSON, comprobación de igualdad profunda y métodos copy. Estos paquetes de generación de código pueden añadir un tiempo de compilación significativo a tus aplicaciones si tienes muchos modelos.

Create separate API models and domain models.
Condicional

Usar modelos separados añade verbosidad, pero evita la complejidad en los ViewModels y casos de uso.

Úsalo en apps grandes.

Estructura de la app

#

El código bien organizado beneficia tanto a la salud de la app misma como al equipo que trabaja en el código.

RecomendaciónDescripción
Use dependency injection.
Muy recomendado

La inyección de dependencias evita que tu app tenga objetos accesibles globalmente, lo que hace que tu código sea menos propenso a errores. Recomendamos usar el paquete provider para manejar la inyección de dependencias.

Use go_router for navigation.
Recomendado

Go_router es la forma preferida de escribir el 90% de las aplicaciones de Flutter. Hay algunos casos de uso específicos que go_router no resuelve, en cuyo caso puedes usar la API Flutter Navigator directamente o probar otros paquetes que se encuentran en pub.dev.

Use standardized naming conventions for classes, files and directories.
Recomendado

Recomendamos nombrar las clases según el componente arquitectónico que representan. Por ejemplo, es posible que tengas las siguientes clases:

  • HomeViewModel
  • HomeScreen
  • UserRepository
  • ClientApiService

Para mayor claridad, no recomendamos usar nombres que puedan confundirse con objetos del SDK de Flutter. Por ejemplo, deberías colocar tus widgets compartidos en un directorio llamado ui/core/, sino en un directorio llamado /widgets.

Use abstract repository classes
Muy recomendado

Las clases Repository son las fuentes de verdad para todos los datos de tu app y facilitan la comunicación con las APIs externas. Crear clases de repositorio abstractas te permite crear diferentes implementaciones, que se pueden usar para diferentes entornos de la app, como "desarrollo" y "staging".

Pruebas

#

Las buenas prácticas de prueba hacen que tu app sea flexible. También hacen que sea sencillo y de bajo riesgo añadir nueva lógica y nueva UI.

RecomendaciónDescripción
Test architectural components separately, and together.
Muy recomendado
  • Escribe pruebas unitarias para cada clase de servicio, repositorio y ViewModel. Estas pruebas deben evaluar la lógica de cada método de forma individual.
  • Escribe pruebas de widgets para las vistas. Probar el enrutamiento y la inyección de dependencias es particularmente importante.
Make fakes for testing (and write code that takes advantage of fakes.)
Muy recomendado

A los fakes no les importa tanto el funcionamiento interno de un método determinado, sino más bien las entradas y salidas. Si tienes esto en cuenta al escribir el código de la aplicación, te verás obligado a escribir funciones y clases modulares y ligeras con entradas y salidas bien definidas.

Recursos recomendados

#
  • Code and templates
    • Código fuente de la app Compass - Código fuente de una aplicación de Flutter robusta y con todas las funciones que implementa muchas de estas recomendaciones.
    • very_good_cli - Una plantilla de aplicación de Flutter creada por los expertos en Flutter Very Good Ventures. Esta plantilla genera una estructura de app similar.
  • Documentation
  • Tooling
    • Herramientas de desarrollo de Flutter - DevTools es una suite de herramientas de rendimiento y depuración para Dart y Flutter.
    • flutter_lints - Un paquete que contiene los lints para las apps de Flutter recomendados por el equipo de Flutter. Usa este paquete para fomentar buenas prácticas de codificación en todo el equipo.

Comentarios

#

Dado que esta sección del sitio web está evolucionando, ¡agradecemos tus comentarios!