The Composable Architecture

Desarrollado por la gente de Point Free, The Composable Architecture es una librería para construir aplicaciones de una forma consistente y entendible.

Puede ser usado con SwiftUI o con UIKit y para cualquier plataforma del ecosistema iOS, esto es, iOS, macOS, tvOS y watchOS.

Es la primera pregunta que me hice y me recordó al comentario de Robert C. Martin. Software es una palabra compuesta, formada por soft y ware. La palabra ware significa producto y la palabra soft suave.

El software se inventó para ser suave, es decir, que cambie con facilidad. En caso contrario, estamos haciendo un software fuerte, es decir, hard.

La dificultad de realizar un cambio debe de ser proporcional tan sólo al alcance del cambio y no a la forma del cambio.

Dicho esto, hay gente que cree que con cumplir determinados principios, como pueden ser los principios SOLID, automáticamente, estamos programando un software con arquitectura limpia.

Otra gente, piensa que con hacer pantallas cumpliendo un determinado patrón, como por ejemplo VIPER, la arquitectura es ya limpia por definición.

La cosa es un poco más sencilla o más compleja, según se quiera ver.

Aquí lanzo lo que considero que deberían de ser los requisitos para una buena arquitectura limpia.

  • Debe hacer que el sistema sea fácil de desarrollar para el equipo que lo hace.
  • Dar visibilidad a los casos de uso del sistema. La arquitectura debe revelar el funcionamiento, los casos de uso, sus características y las entidades que se usen.
  • Disminuir el coste de su mantenimiento, de añadir una nueva funcionalidad o de reparar un defecto.

Un buen arquitecto maximiza el número de decisiones no tomadas.

Todo estos argumentos vienen de la mano a la hora de aplicar The Composable Architecture y lo vamos a ver muy rápido con un ejemplo

Crearemos un nuevo proyecto llamado Ecommerce para SwiftUI

Usaremos SPM para añadir The Composable Architecture.

https://github.com/pointfreeco/swift-composable-architecture

Vamos a crear un carrito de la compra, por lo tanto, necesitaremos una entidad Product.

Un producto tendrá un nombre, por defecto, será desconocido y tendrá un número de items, por defecto, será 0.

The Composable Architecture tiene tres objetos importantes.

  • AppState representa el estado de la aplicación. En nuestro caso, queremos mostrar un carrito de la compra, por lo tanto, el estado de la aplicación será un listado de productos.
  • AppAction representa las acciones de la aplicación. En nuestro caso, queremos incrementar los items de un producto. Podríamos necesitar dos acciones, una para añadir un item y otro para restar un item.
  • AppEnvironment representa las dependencias externas que tendremos. En nuestro caso, no vamos a necesitarlas.

Una vez tenemos definidos los objetos, necesitamos otro objeto que conecte todo y interactúe con la aplicación, el reducer.

Ya solo nos queda definir qué hará cada una de las acciones.

  • addItem incrementará en 1 un producto.
  • minusItem decrementará en 1 un producto, 0 como valor mínimo.
  • Necesitamos crear un objeto de tipo Store.

Con este Store necesitamos instanciarlo en la App y en el preview.

El Store es un objeto que necesita de un estado inicial, de sus posibles acciones que se pueden hacer y de sus dependencias externas.

Ya casi lo tenemos. Nos queda implementar la vista con el Store.

  • WithViewStore es un objeto especial que nos permite acceder a la Store.

¡Ojo! Necesitamos que AppState cumpla con el protocolo Equatable. Esto nos obliga a que Product también lo cumpla.

  • Crearemos un listado y para cada producto mostraremos la información adecuada, un nombre, dos botones y un valor actual de items seleccionados.

En SwiftUI, el objeto List necesita que el objeto que se liste, en este caso Product, cumpla con el protocol Identifiable. Crearemos para cada Product un identificador.

Aparecerá algún error en la construcción de los productos. Lo corregiremos.

Terminamos de construir el listado, usando un listado y recorriendo los objetos a través del objeto viewStore.

Para cada producto, mostraremos un nombre a la izquierda y a la derecha pondremos dos botones, uno para incrementar y el otro para restar items del mismo.

Pues, parece que funciona. Pero, nos queda introducir las acciones. Ya las tenemos y están en la Store.

  • Para añadir un item, ejecutaremos

viewStore.send(.addItem(index: index))

  • Para restar un item:

viewStore.send(.minusItem(index: index))

Con lo cual, si ejecutamos en un simulador o lo probamos directamente en el canvas, ya lo tendremos.

Por último, si queremos testear de una forma fácil, el estado de la aplicación, podemos usar .debug(), igual que hacíamos en RxSwift.

mobile developer