Un Flutter Más Limpio Vol. 5: Estableciendo Casos de Uso

Elian Ortega
5 min readJan 28, 2021

--

Hola y bienvenidos al último volumen en el que hablaremos sobre la capa de dominio de la propuesta de Clean Architecture. La última vez hablamos de una parte fundamental: los repositorios, que nos permiten crear la comunicación de nuestro software con el mundo exterior.

📖 Antes de continuar les dejo el link del volumen anterior: Un Flutter Más Limpio Vol. 4: Contratando Repositorios

En esta ocasión, con los casos de uso vamos a lograr independizar las interacciones específicas del usuario con el sistema, utilizando casos de uso y así obtener código mantenible, reutilizable y que cumpla verdaderamente las necesidades del negocio.

Pero antes de entrar en materia técnica, es importante que recordemos que existen 2 perspectivas: una técnica de un desarrollador y perspectiva de negocios del producto. Esta diferenciación es un tema muy importante, ya que al estar claros de los objetivos del producto podemos desarrollar software de mejor manera.

Recordemos que todo producto de software debería de primero pasar por un proceso donde se definan sus requerimientos y las interacciones de un usuario con el producto de software, ya sea esto un login, agregar un objeto a un carrito de compras, o procesar un pago.

Ok, ahora sí entremos en la materia de hoy.

¿Qué son los casos de uso?

En palabras del Tío Bob…

El software de esta capa contiene las reglas de negocio específicas de la aplicación. Estos encapsulan e implementan todos los casos de uso del sistema.

Te recuerdo que los casos de usos mencionados en la definición no hacen referencia a la parte programada o del software, sino al caso de uso predefinido en la planeación o levantamiento requerimientos del producto.

Cada uno de esos eventos es una interacción del usuario con el sistema y a esto le podemos llamar un caso de uso. Para definir cada uno de estos normalmente se una un diagrama como este:

From: https://warren2lynch.medium.com/use-case-tutorial-for-dummies-8cf426043710

En este tenemos objetos como:

  • Actor: Usuarios que interactúan con el sistema.
  • Caso de uso: Cómo el actor utiliza el sistema para cumplir con alguna funcionalidad.
  • Relaciones: La relación entre los actores los casos de uso

El ejemplo muestra algunos casos de uso de un pasajero en un aeropuerto. Que como mencioné antes, son las interacciones del usuario con el sistema, en este caso la lógica de un aeropuerto.

💡 Si quieren profundizar más sobre estos diagramas y sus componentes, les dejo este artículo: Use cases for dummies.

En el código…

En mi experiencia, he notado que la capa de casos de uso es normalmente obviada y es sustituida utilizando métodos directamente en la lógica de negocios del software. Pero cuando la implementamos logramos mejor desacoplamiento y otras ventajas.

Nuestra estructura de carpetas para la capa de dominio se vería así:

Cumplimos principios…

Repositorios más sencillos. Cuando creamos los casos de usos, logramos facilitar la comunicación con los repositorios y nos aseguramos de tener mejores abstracciones que cumplan con el objetivo específico de ese caso de uso, y como vimos en artículos anteriores, con esto cumplimos el principio de responsabilidad única.

Usamos interfaces no implementaciones. En los casos de uso normalmente vamos a tener dependencia de un repositorio, que mejor dicho debe de ser de una interfaz, de esta manera estaríamos cumpliendo el principio de sustitución Liskov, ya que podríamos sustituir el repositorio por cualquier otro que implemente la misma interfaz y esto no afectará la lógica base de nuestro caso de uso.

Implementación en Dart

Como cualquiera de los componentes de los que hemos hablado a lo largo de la serie, cada uno puede ser implementado de muchas maneras. En esta ocasión con los casos de uso vamos a utilizar uno de los features no muy conocidos de Dart.

En Dart existe algo llamado callable classes. Esto nos permite utilizar la instancia de una clase como si fuera una función. Para lograr esto lo único que tenemos que hacer es implementar el método call() dentro de la clase.

Obtenemos algo así:

Utilizando ese feature de Dart, podemos crear una clase para cada uno de nuestros casos de uso e implementando el método call con la funcionalidad respectiva.

Unamos las piezas

Con toda la información que tenemos ya podemos ver un ejemplo uniendo todas las piezas que llevamos hasta el momento: entidades, repositorios y casos de uso.

El código está simplificado para facilitar el ejemplo. También les recuerdo que para poder entender los ejemplos es importante que hayan leído los artículos previos. Les dejo el anterior: Vol 4: Contratando Repositorios.

Imaginémonos un caso muy sencillo de un signIn, para esto vamos a tener una entidad de usuario y una interfaz de repositorio que contiene un método para realizar el signIn utilizando un email y contraseña.

Aquí es donde muchos desarrolladores deciden no implementar el componente de casos de uso, por lo que realizan llamados a los repositorios directamente desde la lógica de negocios de la aplicación.

Pero como estamos utilizando casos de uso, creamos una clase SignInUser que será nuestro caso de uso. Esta tendrá una dependencia de el AuthRepositoryInterface, luego implementamos el método call() y hacemos el llamado de signIn(). Y así tenemos un caso de uso con responsabilidad única y desacoplamos los repositorios de la lógica de negocios (manejador de estado).

Noten que así no importa quién gane la batalla interminable de cual es el mejor manejador de estado, ya que no importa cuál seleccionemos, o si incluso decidimos cambiar, esto no afecta en nada nuestra implementación.

Este ejemplo es bastante sencillo pero por el momento lo que intentamos es que entiendan cada uno de los componentes que forman parte de esta propuesta de Clean Architecture. Más adelante vamos a hacer ejemplos y videos aplicando toda la teoría con código de producción.

Lo de siempre…

Si aprendiste algo nuevo recordá dejar tu reacción y compartir con tus compañeros desarrolladores/as para que sigamos mejorando como comunidad y desarrollando aplicación de calidad utilizando Flutter.

Para cualquier duda y más contenido pueden contactarme por mis redes que les dejo a continuación:

GitHub, LinkedIn, Twitter, YouTube.

Originally published at http://github.com.

--

--

Elian Ortega
Elian Ortega

Written by Elian Ortega

I focus on writing high-quality, scalable, and testable applications. I like to write articles and make videos about tech.

Responses (1)