Flutter Arquitectura Limpia [1] – Explicación y Estructura

Flutter Arquitectura Limpia [1] – Explicación y Estructura

Mantener su código limpio y probado son las dos prácticas de desarrollo más importantes. En Flutter, esto es aún más cierto que con otros marcos. Por un lado, es bueno hackear una aplicación rápida juntos, por otro lado, los proyectos más grandes comienzan a desmoronarse cuando mezclas la lógica de negocios en todas partes. Incluso los patrones de administración de estado como BLoC no son suficientes en sí mismos para permitir una base de código fácilmente extensible.

Debo aclarar que el contenido original es de Resocoder,  lo que he hecho  es una traducción del contenido. Al final de este artículo está el video en inglés para que vayan ilustrándose mejor y ya tengan una claridad de lo expuesto.

 

Curso TDD Arquitectura Limpia

arquitectura limpia 1

El secreto de las Apps mantenibles y escalables

Aquí es donde podemos emplear una arquitectura limpia y un desarrollo basado en pruebas. Según lo propuesto por nuestro amigable tío Bob, todos debemos esforzarnos por separar el código en capas independientes y depender de abstracciones en lugar de implementaciones concretas.

¿Cómo se puede lograr tal independencia? Aunque nos estamos adelantando un poco, en la imagen de “cebolla” en capas a continuación, las flechas horizontales —> representan el flujo de dependencia. Por ejemplo, las entidades no dependen de nada, los casos de uso dependen solo de entidades, etc.

arquitectura limpia cebolla
Propuesta de Arquitectura Limpia

Todo esto es, bueno, un poco abstracto (juego de palabras). Además, si bien la esencia de la arquitectura limpia sigue siendo la misma para cada marco, el diablo reside en los detalles. Principios como SOLID y YAGNI suenan bien, incluso puedes entender lo que significan, pero no te servirá de nada si no sabes cómo comenzar a escribir código limpio.

 

El proyecto que construiremos

Como con cualquier cosa, la teoría solo puede llevarte tan lejos: el verdadero aprendizaje proviene de hacer. Crearemos una aplicación para obtener datos interesantes sobre los números: ¡una aplicación Number Trivia!

Tiene todos los componentes principales, como obtener datos de una API, caché local, manejo de errores, validación de entrada y más. En cuanto a la gestión estatal, decidí ir con BLoC. ¡No tienes que hacerlo! No puedo enfatizar esto lo suficiente.

La arquitectura limpia no se trata de una técnica particular de gestión del estado. Como verá en poco tiempo, la arquitectura adecuada de su aplicación hará que la elección de la administración estatal sea casi intrascendente. Todavía no elegiría el enfoque StatefulWidget, pero cualquier otra cosa es genial.

 

Arquitectura limpia & Flutter

 

Para dejar las cosas claras y específicas de Flutter, permítanme presentarles la Reso Coder’s Flutter Clean Architecture Proposal™ para demostrar algo, me atrevo a decir, más importante que el flujo de dependencia: flujo de datos y llamadas.

Por supuesto, esta es solo una descripción general de alto nivel que puede o no decirle mucho, dependiendo de su experiencia previa. Diseccionaremos y aplicaremos este diagrama a nuestra aplicación Number Trivia en poco tiempo.

 

Reso Coder's Flutter Clean Architecture Proposal™
Reso Coder’s Flutter Clean Architecture Proposal™

Explicación & Organización del Proyecto

Cada “característica/feature” de la aplicación, como obtener algunas curiosidades interesantes sobre un número, se dividirá en 3 capas: presentationdomaindata. La aplicación que estamos construyendo tendrá solo una característica.

3 capas de una característica
3 capas de una característica

Presentación

003 healthcare and medical

 

Estas son las cosas a las que estás acostumbrado desde la arquitectura Flutter “sucia”. Obviamente necesita widgets para mostrar algo en la pantalla. Estos widgets luego envían eventos al Bloc y escuchan los estados (o un equivalente si no usas Bloc para la administración del estado).

capa de presentación
capa de presentación

Tenga en cuenta que el “Presentation Logic Holder” / “titular de la lógica de presentación” (por ejemplo, Bloc) no hace mucho por sí mismo. Delega todo su trabajo para usar casos. Como máximo, la capa de presentación maneja la conversión y validación de entrada básica.

Aplicado a la aplicación Number Trivia tendremos solo una página con widgets llamada NumberTriviaPage con un solo NumberTriviaBloc.

estructura de la carpeta presentación
estructura de la carpeta presentación

Dominio

dominio
dominio

El dominio es la capa interna que no debería ser susceptible a los caprichos de cambiar las fuentes de datos o portar nuestra aplicación a Angular Dart. Contendrá solo la lógica comercial central (casos de uso) y los objetos comerciales (entidades). Debe ser totalmente independiente de cualquier otra capa.

Los casos de uso son clases que encapsulan toda la lógica empresarial de un caso de uso particular de la aplicación (por ejemplo, GetConcreteNumberTrivia o GetRandomNumberTrivia).

Pero … ¿Cómo es la capa de dominio completamente independiente cuando obtiene datos de un Repositorio, que es de la capa de datos? ¿Ves ese elegante degradado colorido para el repositorio? Eso significa que pertenece a ambas capas al mismo tiempo. Podemos lograr esto con inversión de dependencia.

repositorios son el límite entre data y dominio
repositorios son el límite entre data y dominio

Esa es solo una manera elegante de decir que creamos una clase abstracta de Repositorio que define un contrato de lo que debe hacer el Repositorio: esto entra en la capa de dominio. Luego dependemos del “contrato” del Repositorio definido en el dominio, sabiendo que la implementación real del Repositorio en la capa de datos cumplirá este contrato.

El principio de inversión de dependencia es el último de los principios SÓLIDOS. Básicamente establece que los límites entre capas deben manejarse con interfaces (clases abstractas en Dart).

Aplicado a la aplicación Number Trivia No habrá mucha lógica de negocios para ejecutar en la aplicación, ya que solo mostramos datos numéricos interesantes. En cuanto a los objetos comerciales, habrá una sola entidad bastante delgada llamada NumberTrivia, solo un número y el texto de la trivia.

 

estructura carpeta dominio
estructura de la carpeta carpeta dominio

Data

data
data

La capa de datos consiste en una implementación de Repositorio (el contrato proviene de la capa de dominio) y las fuentes de datos; una es generalmente para obtener datos remotos (API) y la otra para almacenar en caché esos datos. El repositorio es donde usted decide si devuelve datos nuevos o almacenados en caché, cuándo almacenarlos en caché, etc.

Puede notar que las fuentes de datos no devuelven entidades, sino modelos. La razón detrás de esto es que la transformación de datos sin procesar (por ejemplo, JSON) en objetos Dart requiere un código de conversión JSON. No queremos este código específico de JSON dentro de las Entidades de dominio, ¿qué pasa si decidimos cambiar a XML?

La capa data trabaja con modelos, no entidades
La capa data trabaja con modelos, no entidades

Por lo tanto, creamos clases de Modelo que extienden Entidades y agregan algunas funcionalidades específicas (toJson, fromJson) o campos adicionales, como ID de base de datos, por ejemplo.

Aplicado a la aplicación Number Trivia RemoteDataSource realizará solicitudes HTTP GET en la API de Numbers. LocalDataSource simplemente almacenará en caché los datos utilizando el paquete shared_preferences.

Estas dos fuentes de datos se “combinarán” en NumberTriviaRepository, que será la única fuente de verdad para los interesantes datos de trivia numérica.

La política de almacenamiento en caché será muy simple. Si hay una conexión de red, siempre obtenga datos de la API y almacénelos en caché. Luego, si no hay red, devuelva los últimos datos almacenados en caché.

Estructura de la carpeta Data
Estructura de la carpeta Data

Siguiente…

Una vez establecida la estructura fundamental de la arquitectura de la aplicación Number Trivia, comenzaremos a implementar la capa interna y más estable: el dominio. También agregaremos todos los paquetes necesarios para desarrollar la aplicación, incluidos los específicos de prueba como mockito. ¡Estamos haciendo un desarrollo basado en pruebas, después de todo!

 

 

Video

Previous

¿Cómo obtener experiencia en Ciencia de Datos antes de tu primer trabajo?

Flutter Arquitectura Limpia [2] – Entidades y Casos de Uso

Next

Deja un comentario