Arquitectura de Software Design Technology
¿Qué son los patrones de diseño??

¿Qué son los patrones de diseño?

Los patrones de diseño son una parte fundamental del desarrollo de software, ya que brindan soluciones típicas a problemas comúnmente recurrentes en el diseño de software. En lugar de proporcionar piezas específicas de software, los patrones de diseño son simplemente conceptos que se pueden usar para manejar temas recurrentes de manera optimizada.

Además, en los últimos años, el ecosistema de desarrollo web ha cambiado rápidamente. Mientras que algunos patrones de diseño bien conocidos pueden simplemente no ser tan valiosos como solían ser, otros han evolucionado para resolver problemas modernos con las últimas tecnologías.

Introducción a patrones de diseño

La biblioteca de JavaScript de Facebook, React, ha ganado una enorme tracción en los últimos 5 años y actualmente es el package descargado con más frecuencia en NPM en comparación con las bibliotecas de JavaScript de la competencia, como Angular, Vue, Ember y Svelte.

Debido a la popularidad de React, los patrones de diseño se han modificado, optimizado y se han creado nuevos para proporcionar valor en el ecosistema de desarrollo web moderno actual. La última versión de React introdujo una nueva función llamada Hooks, que juega un papel muy importante en el diseño de su aplicación y puede reemplazar muchos patrones de diseño tradicionales.

El desarrollo web moderno involucra muchos tipos diferentes de patrones. Este proyecto cubre la implementación, los beneficios y las dificultades de los patrones de diseño comunes usando ES2015+, los patrones de diseño específicos de React y su posible modificación e implementación usando React Hooks, y muchos más patrones y optimizaciones que pueden ayudar a mejorar su aplicación web moderna.

Composition Pattern (Composition vs Inheritance)

React tiene un potente modelo de composición, y recomendamos usar composición en lugar de herencia para reutilizar código entre componentes.

¿Qué es la composición (React Composition)?

La composición es el acto de combinar partes o elementos para formar un todo.
Los componentes son los “building blocks” básicos de la interfaz de usuario en las aplicaciones React, al igual que las funciones puras son los componentes básicos de la composición de funciones.

React Composition es un patrón de desarrollo basado en el modelo de componentes original de React en el que construimos componentes a partir de otros componentes utilizando accesorios definidos explícitos o los accesorios secundarios implícitos.

En términos de refactorización, la composición de React es un patrón que se puede usar para dividir un componente complejo en componentes más pequeños y luego componer esos componentes más pequeños para estructurar y completar su aplicación.

.

¿Por qué usar la composición?

Esta técnica evita que construyamos demasiados componentes similares que contengan código duplicado y nos permite construir menos componentes que puedan reutilizarse en cualquier lugar dentro de nuestra aplicación, haciéndolos más fáciles de entender y mantener para su equipo.

Contención

Algunos componentes no conocen a sus hijos de antemano. Esto es especialmente común para componentes como Sidebar o Dialog que representan “cajas” genéricas.

En este tipo de componentes contenedor se usa la prop especial “children” para pasar elementos hijos directamente en su resultado:

patrones de diseño

Esto permite que otros componentes les pasen hijos arbitrarios anidando el JSX:

patrones de diseño 2

Especialización

A veces pensamos en componentes como “casos concretos” de otros componentes. Por ejemplo, podríamos decir que un WelcomeDialog es un caso concreto de Dialog.

patrones de diseño 3

Entonces... ¿qué pasa con la herencia?

En la documentación de grandes compañías (Facebook, Tesla, Airbnb),  que usan React en miles de componentes aseguran que no han encontrado ningún caso de uso en el que recomendaría crear jerarquías de herencia de componentes.

Las props y la composición te dan toda la flexibilidad que necesitas para personalizar el aspecto y el comportamiento de un componente de forma explícita y segura. Recordemos que los componentes pueden aceptar props arbitrarias, incluyendo valores primitivos, elementos de React y funciones.

Si quieres reutilizar funcionalidad que no es de interfaz entre componentes, sugerimos que la extraigas en un módulo de JavaScript independiente. Los componentes pueden importarlo y usar esa función, objeto, o clase, sin extenderla.

En React, el uso de Composición y accesorios le brinda toda la flexibilidad que necesitaría. React no dice que la composición es mejor que la herencia. La composición encaja mejor dentro de la estructura de componentes de React.

Composition via React Hooks

React 16.8 introdujo una nueva función llamada Hooks. Los Hooks hacen posible el uso de métodos de estado y ciclo de vida de React, sin tener que usar un class component

Aunque los Hooks no son necesariamente un patrón de diseño, estos juegan un papel muy importante en el diseño de su aplicación. Muchos patrones de diseño tradicionales pueden ser reemplazados por los Hooks.

Pequeño viaje al pasado de React

Antes de que se introdujera Hooks en React, teníamos que usar class components para agregar métodos de estado y ciclo de vida a los componentes. Un componente de clase típico en React puede parecerse a:

viaje al pasado de React
viaje al pasado de React 2

Un class component puede contener un estado en su constructor, métodos de ciclo de vida como componenteDidMount y componenteWillUnmount para realizar efectos secundarios basados ​​en el ciclo de vida de un componente y métodos personalizados para agregar lógica adicional a una clase.

Aunque todavía podemos usar class component después de la introducción de React Hooks, el uso de class component puede tener algunas desventajas. Veamos algunos de los problemas más comunes al usar componentes de clase. Yo, particularmente, no recomendaría usarlo bajo ningún concepto.

Restructuring

La forma común de compartir código entre varios componentes es mediante el uso del Higher-Order-Components o Render Props, ambos son interpretaciones del tema principal de ese tip : Composition Design Pattern. Aunque ambos patrones son válidos y una buena práctica, agregar esos patrones en un momento posterior requiere que reestructure su aplicación.

Además de tener que reestructurar su aplicación, que es más complicado cuanto más grandes son sus componentes, tener muchos componentes envolventes para compartir código entre componentes anidados más profundos puede conducir a algo que se conoce mejor como “Wrapper Hell”. No es raro abrir sus herramientas de desarrollo y ver una estructura similar a:

Si este dataObject en algún momento se le añade otra propiedad: dataObject.property2 = ‘test’ ésta vez, sí sería reactiva.

A parte de la evidente mejora del reactividad en profundidad, la reactividad se vuelve más concisa y explícita, permitiéndonos ahora hacer reactivo lo que queramos

Hooks

Está bastante claro que los class components no siempre son una gran característica en React. Para resolver los problemas comunes con los que se pueden encontrar los desarrolladores, React introdujo React Hooks. Los Hooks son funciones que puede usar para administrar el estado de los componentes y los métodos del ciclo de vida. Sus principales funcionalidades son:

  • Agregar estado(state) a un componente funcional.
  • Administrar el ciclo de vida de un componente sin tener que usar métodos de ciclo de vida como componenteDidMount y componenteWillUnmount
  • Reutilizar la misma lógica con estado entre múltiples componentes en toda la aplicación.

Aqui listo brevemente algunos hooks nativos de React y para que se utilizan:

useState

React proporciona un hook que administra el estado dentro de un componente funcional, llamado useState.

  1. El valor actual del state.
  2. El método con el que podemos actualizar el estado.

UseEffect

Hemos visto que podemos usar el componente useState para manejar el estado dentro de un componente funcional, pero otro beneficio de los componentes de clase fue la posibilidad de agregar métodos de ciclo de vida a un componente.

Con el hook useEffect, podemos «engancharnos» al ciclo de vida de un componente. El hook useEffect combina de manera efectiva los métodos de ciclo de vida componentDidMount, componentDidUpdate y componentWillUnmount.

Visto esto, en el siguiente ejempo les muestro como quedaria el component Input refactorizado usando funcitonal components y hooks :

función imput

Custom hooks

El propósito de crear un custom hooks es extraer la lógica de un componente y convertirlo en un hook reutilizable

Se utiliza un custom hook para evitar crear demasiados componentes similares que comparten la misma lógica. También mejora el código de su aplicación al eliminar el código duplicado, lo que facilita el mantenimiento de su aplicación. Al introducir una nueva feature en la aplicación, la creación de un custom hook nos impide implementar esa misma feature nueva en cada componente construido de manera similar. En su lugar, ahora podemos reutilizar un custom hook. A continuación, veamos algunos ejemplos.

Ejemplos

ejemplo patrones de diseño
ejemplo patrones de diseño 2

Exploremos una similitud entre estos dos componentes.

Problema: observe cómo tanto el componente Accordion como el componente Editable comparten la misma funcionalidad, donde ambos dependen de un valor booleano y de una función para actualizar ese valor booleano; en otras palabras, una funcionalidad de alternancia (toggle).

Solución: podemos usar un custom hook que nos permitirá reutilizar esta lógica de alternancia en ambos componentes y en cualquier componente nuevo que se agregue en el futuro.

Vamos a crear un custom hook llamado useToggle que devuelva un status de estado y una función de controlador toggleStatus:

useToggle

La lógica de alternancia implementada en useToggle es útil en los siguientes escenarios:

  • Ocultar/Mostrar un componente
  • Contraer/Expandir un componente

Ahora podemos reutilizar nuestro nuevocustom hook tantas veces como sea necesario en cualquier componente que aproveche el uso de esta lógica compartida.

Recapitulación

  1. Los componentes se pueden componer con uno o muchos otros componentes.
  2. Los componentes nunca saben quiénes son sus padres.
  3. En el modelo de composición de React, algunos componentes no saben quiénes son sus hijos antes de tiempo (también podríamos decir en el momento de la implementación). El prop infantil mejora el enfoque declarativo de React.
  4. Los React Hooks permiten la composición perpendicular al árbol al permitir la reutilización de la lógica de componentes dentro de diferentes componentes. De esta forma, no cambiamos la jerarquía de componentes al reutilizar la lógica de componentes. Además, estos te permiten dividir un componente en funciones más pequeñas que se pueden reutilizar en diferentes componentes.
  5. La composición hará que su código sea más reutilizable, más fácil de mantener y más fácil de probar. ¡Viva la composición!

Conclusión

Para resumir, los principios detrás de la composición y la herencia en React no difieren de la composición y la herencia en términos generales de desarrollo de software. Dicho esto, hay algunas pequeñas consideraciones en React, por ejemplo, el tamaño del paquete que no importaría mucho en un entorno del lado del servidor.

La herencia es un enfoque rígido y estrechamente acoplado. Cada antepasado en la jerarquía agrega una capa de acoplamiento.

Cuando reutilizamos un caso de uso de una clase determinada al heredar de ella, también traemos todo el código implícito de los ancestros, incluso el código de los casos de uso que no usamos. En JavaScript eso significa más código para agrupar. Este código adicional también es más difícil de optimizar y reducir el tamaño, por ejemplo, reduciendo la cantidad de caracteres de los nombres de los métodos o las propiedades de las clases.

Debido al estrecho acoplamiento, los cambios en la clase base podrían potencialmente romper cualquiera de las clases descendientes. La probabilidad de interrumpir los cambios aumenta cuando amplía una clase implementada por un autor externo. Por esta razón nunca debe extender una clase que extienda React Componente; su componente extiende React. El componente y la herencia deberían detenerse allí.

// ¿Quieres saber más sobre Design Patterns?

¡Contacta con nosotros!

Author

Sandra Ciruelos

Leave a comment

Tu dirección de correo electrónico no será publicada.