Breve introducción a las arquitecturas limpias.
Tags: javascript, beginners, webdev, programming
Published: 2022-10-09 12:54:03

En este artículo trataré de describir de forma muy breve y quizá algo inexacta el concepto de arquitectura limpia en el contexto del software.

"Arquitectura limpia" es el título del libro de Robert C Martin en el que expone y desarrolla el concepto.

## Arquitectura de software

Citando a Robert, _"La arquitectura de un sistema de software es la forma en la que se organizan los componentes que lo forman y la forma en la que se comunican entre sí"_.

En proyectos pequeños como prácticas de clase la importancia de tener una buena arquitectura puede no ser muy evidente pero a medida que los proyectos crecen se hace más y más claro su importancia.

Uno de los mejores ejemplos que he visto para ilustrar esta importancia [es la siguiente imagen](https://dev.to/huytaquoc/a-different-approach-to-frontend-architecture-38d4):

![](https://res.cloudinary.com/practicaldev/image/fetch/s--uwSQ0rQI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.ctfassets.net/1es3ne0caaid/4qnEjwkNAIiAmYcms8iKua/5173990eceb6223dc08e6607636dcc48/clean-architecture-ex-1.jpeg)

¿Qué nudos tienes que deshacer para separar la grapadora del resto de componentes?

Ahora mira esta imagen:

![](https://res.cloudinary.com/practicaldev/image/fetch/s--w1qI3JJr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.ctfassets.net/1es3ne0caaid/2Qd2FVYAqIEowM0GySIMyM/5d6acdc87b8149732a6b750fcb09c4b7/clean-architecture-ex-2.jpeg)

Pues con el software pasa lo mismo, sin entrar en detalles buscamos reducir **la dependencia **de cada una de las piezas y que cada cosa esté en su lugar.

## Dependencia

Es muy difícil resumir el concepto de dependencia / acoplamiento de software. Una de las maneras más formales que conozco para medir y cuantificar la dependencia de cada una de las piezas del software es la ["conasence" o ¿"Conacimiento"?](https://connascence.io/).

Resumiéndolo mucho podemos decir que _"una pieza `A` depende de una pieza `B` si cambios en la pieza B afectan de alguna forma a la pieza A"_

En la primera foto podemos decir que todos los utensilios están acoplados entre si, porque para mover las tijeras tenemos que mover el bolígrafo y para mover el bolígrafo tenemos que mover la grapadora...

En la segunda foto este acoplamiento se reduce mucho y las tijeras sólo están acopladas al taco de post-it.


## Arquitecturas limpias

Las arquitecturas limpias buscan reducir el acoplamiento organizando las piezas en 3 grandes bloques: Dominio, Aplicación y Presentación. La dependencias se organizan de forma que las capas más centrales no saben nada de las capas exteriores.


![](https://i0.wp.com/jasontaylor.dev/wp-content/uploads/2020/01/Figure-01-2.png?resize=531%2C531&ssl=1)

### Dominio

Es donde se definen nuestros **objetos de negocio.**  Por ejemplo si estamos trabajando en una entidad bancaria, una `hipoteca` o un `cliente` serían objetos de negocio.

Estos objetos se pueden representar con clases y no tienen absolutamente ninguna dependencia (no importan otros archivos).

```js
export default class Mortgage {
	constructor(amount, years, rate) {
		this.amount = amount;
		this.years = years;
		this.rate = rate;
	}
}
```

```js
export default class Client {
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}
}
```

### Aplication

Por encima del dominio tenemos las reglas de negocio. Estas reglas conocen los objetos de dominio y junto a estos definen nuestra **lógica de negocio**

Por ejemplo _"No conceder préstamos a más de 20 años vista a personas mayores de 40 años"_

```js
/**
 * Esta función recibe como parámetro una hipoteca y un cliente y devuelve
 * true o false según se pueda conceder o no esta hipoteca. 
 *
 * Cambios en la clase hipoteca o en la clase Cliente pueden 
 * afectar a esta función y decimos que están acopladas.
 *
 * Siendo estrictos podemos decir que tenemos 
 * [conacimiento de tipo](https://connascence.io/type.html) 
 * en los parámetros
 *
 */
function checkIfMortageCanBeGranted(mortage, client) {
	if(client.age > 40 && mortage.years > 20) {
		return false;
	}
	
	// ... Asumimos que habría mas reglas de negocio
	
	// Finalmente devolvemos true para conceder la hipoteca
	return true;
}

```

### Presentación

En esta última capa tendremos toda la lógica necesaria para presentar nuestra lógica de negocio al cliente final. Podríamos escribir una aplicación en React, una aplicación en Vue o incluso un asistente de voz escrito en javascript.

Nuestra lógica de negocio y nuestros objetos de dominio **son iguales independientemente de la tecnología elegida para la vista** y pueden ser utilizados por una app escrita en Angular, por una app escrita en Vue o por una app escrita en React. Además podemos escribir tests unitarios que comprueben este comportamiento de forma totalmente aislada para verificar que los requisitos son correctos.

De nuevo, lo importante es que gracias a aplicar una arquitectura limpia **tanto los objetos de dominio no están acoplados a la lógica de negocio y la lógica de negocio a su vez es independiente de la presentación.**. Esto hace que cuando tengamos que mantener una aplicación grande tengamos muchísimo más claro qué nudos hay que deshacer para reemplazar la grapadora por una más moderna.


## Enlaces

- [https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
- [https://www.amazon.com/Clean-Architecture-Craftsmans-Software-Structure/dp/0134494164](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
- [https://leanpub.com/pppsd](https://leanpub.com/pppsd)