Introducción a los patrones de diseño y arquitectura de software.
Tags: programming, learning, computerscience, designpatterns
Published: 2023-10-15 17:42:28

Después de algunos años de inactividad y resolver uno que otro problema con la plataforma, he decidido volver a escribir algunos artículos sobre lo que he aprendido en este tiempo como desarrollador fullstack. Quiero, por encima de todo, abordar algunos temas teóricos que creo son interesantes y que todo software engineer debería conocer.

Así es, hoy inicia una serie de artículos sobre patrones de diseño y arquitectura del software, conocimientos curiosamente desconocidos a profundidad por muchos en la industria y sobre todo por los desarrolladores que vienen de bootcamps, que, debido a la premura con la que son introducidos al mundo del desarrollo, suelen perderse de mucha información realmente útil y necesaria en sus roles.

Empecemos por esta simple pregunta: **¿Qué son los patrones de diseño?** Para responder a esta interrogante, debemos entender que tanto los patrones de diseño como las arquitecturas de software son principalmente las ideas que han implementado, perfeccionado y estandarizado otros desarrolladores a lo largo de los años. Son ideas para solucionar problemas comunes, sencillos y también complejos. Esto significa que algunos patrones nacen y mueren.

Si me preguntan a mí directamente, diría que, a pesar de que los patrones de diseño y arquitectura están estrechamente ligados, sus diferencias básicas son las siguientes: el primero trata sobre los métodos para controlar cómo fluye la información dentro de un sistema, mientras que el segundo trata sobre "The shape of things" o la forma de las cosas, proporcionando principalmente un marco de trabajo general para cubrir las necesidades del proyecto a largo plazo. Es importante destacar que, aunque no lo sepamos, si utilizamos algún framework como Express en Node.js, estamos utilizando una gran cantidad de patrones de diseño.

#### ¿Quieres realizar validaciones secuencialmente en un endpoint?
Patrón mediator/middleware.


#### ¿Quieres distribuir alguna lógica de negocio en múltiples archivos y poder exportar e importar lo que necesites de ellos?
Patrón module.


#### ¿Estás trabajando en el frontend con React y quieres compartir la data a través de componentes hijos?

Patrón Provider.

####¿ Se te está haciendo complicado controlar todo el flujo de datos a través de los componentes?
Sencillo, utiliza algún manejador de estado como Redux para resolverlo. Adivina qué, estás utilizando el Patrón Flux.

Podríamos seguir indagando un buen rato para darnos cuenta de que son parte de nuestro trabajo en cada momento, estemos conscientes de ello o no. Sin embargo, conocer estos temas es sin duda una excelente ayuda para afrontar los problemas cotidianos y facilitarnos el aprendizaje de nuevas tecnologías, pues estas cambian, pero las bases son las mismas para todas.

Lo mismo ocurre con el tema de la arquitectura. ¿Te imaginas hoy en día encontrarte con una API de un CRM, por ejemplo, y que todos los archivos (digamos 50, por poner una cantidad) estén en un mismo nivel de carpeta? Bueno, lamentablemente, cosas parecidas suceden aún a día de hoy porque siempre hay algún degenerado. Pero, ¿qué tal si usáramos una **arquitectura orientada a servicios**?

```
app
├── common
│   ├── config
│   │   └── app.config.ts
│   ├── dtos
│   │   ├── user.dto.ts
│   │   └── product.dto.ts
│   └── services
│   	└── logger.service.ts
├── modules
│   ├── users
│   │   ├── controllers
│   │   │   └── user.controller.ts
│   │   ├── interfaces
│   │   │   └── user.interface.ts
│   │   └── services
│   │   	└── user.service.ts
│   └── products
│   	├── controllers
│   	│   └── product.controller.ts
│   	├── interfaces
│   	│   └── product.interface.ts
│   	└── services
│       	└── product.service.ts
└── main.ts
```

Como se ve a simple vista, está organizado y encontrar cualquier cosa, así como entender las responsabilidades de cada uno, es mucho más sencillo ahora. Claro, al principio definir una arquitectura o un patrón puede llegar a ser tedioso y puede parecer que estamos convirtiendo el código en algo aburrido, pero a mediano y largo plazo nos estaremos ahorrando muchos dolores de cabeza a la hora de agregar nuevos features a producción.

#### Orígenes
Segun mis investigaciones, El origen no viene exactamente de un ingeniero de software, sino de un arquitecto de entornos urbanos (y profesor universitario) llamado [Christopher Alexander](https://es.wikipedia.org/wiki/Christopher_Alexander), el cual en su libro A Pattern Lenguage, en los años 1970, Utiliza un enfoque similar a la gramática generativa para describir una serie de reglas que se aplican a un conjunto de elementos básicos para generar un diseño urbano.

Por ejemplo el **Patrón Nº18**: **Learning Network** o "**Red de aprendizaje**" describe cómo crear un entorno que facilite el aprendizaje de las personas. Alexander sostiene que el aprendizaje es más efectivo cuando ocurre en un entorno social, donde las personas pueden interactuar entre sí y compartir sus conocimientos.



##### ¿Como lo hacemos?

- Creando espacios para que las personas se reúnan y compartan ideas.

- Ofreciendo oportunidades para que las personas trabajen juntas en proyectos.

- Fomentando el intercambio de conocimientos y experiencias.

- Proporcionando acceso a recursos de aprendizaje.

- Creando un ambiente de apoyo y colaboración.


Ya en el campo de la ingeniería de software, años después en los 90's saldría lo que para algunos es la obra fundacional de los patrones de diseño de software **Patrones de diseño: Elementos de software orientado a objetos reutilizables** de rich Gamma, Richard Helm, Ralph Johnson y John Vlissides Que a decir verdad todos tienen una notable trayectoria en la industria y en su libro exponen lo que hoy en dia son patrones bastante populares y comunes como:

- **Singleton**: garantiza que solo exista una instancia de una clase.
- **Factory**: crea objetos de una clase concreta.
- **Adapter**: permite que dos clases que no son compatibles interactúen entre sí.
- **Proxy**: proporciona una representación de un objeto real.
- **Command**: encapsula una solicitud como un objeto.
- **Observer**: permite que un objeto notifique a otros objetos de cambios en su estado.
- **Strategy**: permite que un objeto cambie su comportamiento en tiempo de ejecución.

#### ¿Y la arquitectura?
La necesidad de una buena arquitectura viene desde que existen los primeros sistemas informaticos, Tengamos en cuenta que al inicio, el bajo poder de procesamiento del hardware de la epoca hacia que los programadores tuvieran que hacer verdaderas proesas para hacer que el codigo fuese lo mas eficiente posible y a medida que los sistemas fueron haciendose mas grandes y mas complejos tambien surgia la necesidad de organizar el codigo de forma mas estructurada.

Así es como nace **Structured Programming** de [Edsger Dijkstra](https://es.wikipedia.org/wiki/Edsger_Dijkstra), un libro fundamental en la evolución de la ingeniería de software y cuyo autor hizo muchos aportes a la profesión hasta el punto de que actualmente hay un [premio con su nombre](https://es.wikipedia.org/wiki/Premio_Dijkstra) por sus aportes a la [computación distribuida](https://es.wikipedia.org/wiki/Computaci%C3%B3n_distribuida).

Dijkstra promovia el uso de estructuras de control simples para hacer el codigo lo mas legible y descriptible posible, aunque no como algo nuevo, promovia la modularización, al crear programas que cumplieran funciones claras y especificas y no un solo programa con toda la logica en dentro, siendo base fundamental para la creacion de lenguajes mas estructurados como c, Y ya en una opinion personal, sentando las bases del clean code.


Como podran darse cuenta, son temas comunes en el dia dia como desarrolladores pero al mismo tiempo pueden llegar a ser bastante complejos y extensos, Así que, animo a todos los desarrolladores, ya sean recién llegados o experimentados, a explorar y dominar estos temas. No solo mejorarán sus habilidades técnicas, sino que también les permitirán abordar los desafíos cotidianos con confianza, Gracias por acompañarme en este primer artículo de la serie. Espero que hayas encontrado esta introducción a los patrones de diseño y la arquitectura del software útil y motivadora, Nos vemos en el próximo artículo.