Diseñar patrones en el desarrollo moderno de JavaScript

El autor del material, cuya traducción publicamos, dice que en el mundo del desarrollo de software, el "diseño arquitectónico" puede llamarse el proceso de construcción de la aplicación, durante el cual se esfuerzan por hacer que sea de alta calidad, confiable y adecuada para el soporte. Además, los patrones de diseño (patrones) le permiten operar con conceptos que son enfoques para resolver problemas comunes. Estas decisiones pueden variar de abstractas, conceptuales a muy específicas. Su conocimiento permite a los desarrolladores comunicarse de manera efectiva entre sí.

Si al menos dos desarrolladores en un equipo entienden los patrones, hablar sobre resolver los problemas que enfrenta el equipo se vuelve muy productivo. Si solo un miembro del equipo conoce los patrones, por lo general sucede que aclara lo que sabe a otros miembros del equipo.

imagen

El propósito de este artículo es interesar a los lectores con una especie de presentación formal del conocimiento en el campo del desarrollo de software, mostrándoles la idea de los patrones de diseño y describiendo varios patrones que son interesantes porque encuentran aplicación en el desarrollo moderno de JavaScript.

Patrón Singleton


▍ General


El patrón de diseño "singleton" (también llamado "singleton") no se puede llamar uno de los patrones más utilizados, pero comenzamos la conversación con él, ya que es relativamente fácil de entender.

Este patrón surge del concepto matemático de un singleton: un conjunto de singleton, es decir, un conjunto que contiene solo un elemento. Por ejemplo, el conjunto {nulo} es un singleton.

En el campo del desarrollo de software, el significado del patrón "singleton" se reduce al hecho de que limitamos el número de instancias posibles de una determinada clase a un objeto. En el primer intento de crear un objeto basado en una clase que implementa este patrón, dicho objeto se crea realmente. Todos los intentos posteriores de crear una instancia de la clase devolverán el objeto creado durante el primer intento de obtener una instancia de la clase.


¿Por qué otro superhéroe cuando tenemos a Batman?

Arriba hay un ejemplo de una clase que implementa el patrón singleton.

▍ ¿Por qué es necesario?


Está claro que este patrón nos permite limitarnos a un solo "superhéroe" (obviamente es Batman). ¿Pero por qué más podría necesitarlo?

Aunque este patrón no está exento de problemas (anteriormente se llamaba maldad, dado que el singleton se llama mentirosos patológicos ), en algunas situaciones, puede ser muy útil. Una de estas situaciones es inicializar objetos de configuración. En una aplicación típica, tiene sentido mantener solo una instancia de dicho objeto, a menos que, de acuerdo con las características del proyecto, se utilicen varios objetos similares en él.

▍Dónde usarlo?


El principal ejemplo de uso del patrón singleton en grandes marcos populares son los servicios angulares. La documentación angular tiene una página separada que explica cómo hacer que un servicio sea un singleton.

El diseño de servicios en forma de singletones tiene un significado profundo, ya que los servicios se utilizan como repositorios de estado, configuración y le permiten organizar la interacción entre los componentes. Todo esto lleva al hecho de que el desarrollador necesita para que su aplicación no tenga varias instancias del mismo servicio.

Considera un ejemplo. Supongamos que tenemos una aplicación simple que se usa para contar la cantidad de clics en los botones.


Cada clic en cualquiera de los botones actualiza el contador

El número de clics en los botones debe almacenarse en un objeto, que implementa las siguientes características:

  • Le permite contar clics en botones.
  • Permite leer el valor actual del contador de clics.

Si dicho objeto no fuera un singleton (y cada botón tuviera su propia instancia de dicho objeto asociado), el programa calcularía incorrectamente el número de clics en los botones. Además, con este enfoque, es necesario resolver el siguiente problema: "¿De qué objeto particular responsable de contar los clics se tomarán los datos que se muestran en la pantalla?"

Patrón de observador


▍ General


Un patrón de observador es un patrón de diseño en el que un objeto llamado sujeto mantiene una lista de objetos dependientes llamados observador y los notifica automáticamente cuando cambia su estado, generalmente llamando a uno de sus métodos .

Comprender este patrón no es difícil si encuentra su analogía en el mundo real. A saber, estamos hablando de suscripciones a periódicos.

Supongamos que normalmente compra periódicos en un quiosco. Vas allí, preguntando si hay un nuevo número de tu periódico favorito. Si lo que necesita no está en el quiosco, entonces se va a su casa, pierde el tiempo y luego vuelve al quiosco. Si consideramos que esta situación se aplica a JavaScript, sería como una encuesta cíclica de alguna entidad, realizada hasta que se reciban los datos necesarios.

Después, cuando finalmente obtenga el periódico que necesita, puede comenzar a hacer todo lo que ha estado luchando todo este tiempo: tomar una taza de café y desplegar el periódico. En JavaScript, esto equivaldría a llamar a una devolución de llamada, que íbamos a llamar después de obtener el resultado deseado.


Finalmente puedes leer el periodico

Sería mucho más razonable hacer esto: suscríbase a un periódico y reciba su último número todos los días. Con este enfoque, el editor le informará que se ha publicado un nuevo número del periódico y se lo entregará. Ya no tienes que ir al quiosco. No más pérdida de tiempo.

Si cambia a JavaScript nuevamente, significa que ya no tendrá que esperar en el ciclo para obtener algún resultado y, después de recibirlo, invocar una determinada función. En cambio, le informa al sujeto que está interesado en ciertos eventos (mensajes) y le pasa la función de devolución de llamada, que debe llamarse cuando los datos de interés estén listos. Tú, en este caso, te conviertes en un observador.


Ahora nunca te perderás tu periódico matutino favorito

El patrón en cuestión tiene una característica agradable: no tiene que ser el único observador. Si no puede obtener su periódico favorito, le molestará. Pero lo mismo sucederá con otras personas que no pueden comprarlo. Es por eso que varios observadores pueden suscribirse a un tema.

▍ ¿Por qué es necesario?


El patrón "observador" se usa en muchas situaciones, pero generalmente se debe usar cuando se desea crear una relación de uno a muchos entre los objetos y, al mismo tiempo, dichos objetos no deben estar fuertemente conectados. Además, el sistema debería poder notificar un número ilimitado de objetos sobre ciertos cambios.

Las aplicaciones de JavaScript son un excelente lugar para aplicar el patrón de observador, ya que aquí todo se basa en eventos y, en lugar de referirse constantemente a una determinada entidad para averiguar si ha ocurrido un evento de interés para usted, será mucho mejor que le avise cuando la ocurrencia de este evento (esto es similar al viejo dicho: "No nos llame. Cuando sea necesario, lo llamaremos nosotros mismos").

Es probable que ya haya utilizado diseños que se asemejan al patrón de observación. Por ejemplo, esto es addEventListener . Agregar un detector de eventos a un elemento tiene todos los signos de usar el patrón de observador:

  • Puedes suscribirte al objeto.
  • Puede darse de baja del objeto.
  • Un objeto puede informar a todos sus suscriptores sobre el evento.

Es útil saber acerca de la existencia del patrón de "observador" en el sentido de que este conocimiento le permite realizar su propio tema, o mucho más rápido que antes, para encontrar una solución existente utilizando este patrón.

▍Dónde usarlo?


La implementación básica de este patrón no tiene que ser particularmente complicada, pero existen excelentes bibliotecas que lo implementan y se utilizan en muchos proyectos. Estamos hablando del proyecto ReactiveX y su versión JavaScript de RxJS .

La biblioteca RxJS permite no solo suscribirse a los sujetos, sino que también le brinda al programador la capacidad de transformar datos de varias maneras, le permite combinar muchas suscripciones y mejora la capacidad de administrar operaciones asincrónicas. Además, sus capacidades no se limitan a esto. Si alguna vez quisiste aumentar las capacidades de tus programas para procesar y convertir datos a un nivel superior, entonces puedes recomendar estudiar la biblioteca RxJS.

Además del patrón "observador", el proyecto ReactiveX puede estar orgulloso de la implementación del patrón "iterador", que permite al sujeto informar a los suscriptores sobre la finalización de la suscripción, en esencia, lo que permite cancelar la suscripción por iniciativa del sujeto. En este artículo no voy a hablar sobre el patrón "iterador", pero puedo decir que si recién está comenzando a aprender patrones de diseño, estudiar este patrón y pensar cómo se compone con el patrón "observador" puede ser un buen ejercicio.

Patrón de fachada


▍ General


El patrón de fachada recibió su nombre de la arquitectura. En arquitectura, una fachada suele ser uno de los lados externos de un edificio, generalmente el frente. Inglés tomó prestada la palabra "fachada" del francés. Estamos hablando de la palabra "fachada", que, entre otras cosas, se traduce como "la parte frontal del edificio".

La fachada del edificio en arquitectura es el exterior del edificio, ocultando lo que hay dentro. Se pueden observar propiedades similares en el patrón de "fachada", ya que está destinado a ocultar mecanismos internos complejos detrás de una determinada interfaz externa. Su aplicación permite al desarrollador trabajar con una API externa, organizada de manera bastante simple y, al mismo tiempo, proporciona la capacidad de cambiar los mecanismos internos ocultos detrás de la fachada, sin interrumpir el rendimiento del sistema.

▍ ¿Por qué es necesario?


El patrón de "fachada" se puede utilizar en una gran cantidad de situaciones, entre las que podemos destacar especialmente aquellas que intentan hacer que el código sea más fácil de entender (es decir, ocultan mecanismos complejos detrás de API simples), y aquellas en las que los fragmentos de sistemas tienden a generar la mayor cantidad posible más flojo conectado el uno al otro.


Estos objetos necesitan algo de la guarida del dragón.

Es fácil ver que un objeto de fachada (o una capa con varios objetos) es una abstracción muy útil. Es poco probable que alguien quiera toparse con un dragón si esto se puede evitar. El objeto de fachada es necesario para proporcionar otros objetos con una API conveniente, y este objeto hará frente a todos los trucos del dragón por sí solo.

Otra característica útil del patrón de "fachada" es que el dragón se puede "rehacer" como se desee, pero esto no afectará otras partes de la aplicación. Supongamos que desea reemplazar un dragón con un gatito. El gatito, como el dragón, tiene garras, pero es más fácil de alimentar. Cambie el dragón a un gatito, esto significa, para reescribir el código del objeto de fachada sin hacer cambios en los objetos dependientes.

▍Dónde usarlo?


El patrón de fachada a menudo se encuentra en Angular. Allí, los servicios se utilizan como un medio para simplificar cierta lógica básica. Pero este patrón es aplicable no solo en Angular, a continuación puede ver esto.

Supongamos que necesitamos agregar un sistema de administración de estado a la aplicación. Para resolver este problema, puede usar varias herramientas, entre ellas - Redux, NgRx, Akita, MobX, Apollo, así como - nuevas herramientas constantemente emergentes. ¿Por qué no probarlos todos?
¿Cuál es la funcionalidad principal que debe proporcionar una biblioteca de administración de estado? Estas son probablemente las siguientes características:

  • Un mecanismo para notificar al sistema de gestión estatal que necesitamos cambiar de estado.
  • El mecanismo para obtener el estado actual o su fragmento.

Todo no se ve tan mal.

Ahora, armado con el patrón de "fachada", puede escribir fachadas para trabajar con varias partes del estado, proporcionando API convenientes que se pueden usar en el programa. Por ejemplo, algo como facade.startSpinner() , facade.stopSpinner() y facade.getSpinnerState() . Dichos métodos son fáciles de entender, puede consultarlos fácilmente en una conversación sobre el programa.

Después de eso, puede trabajar con objetos que implementan el patrón de "fachada" y escribir código que transformará su código para que pueda funcionar con Apollo (administrar el estado con GraphQL es un tema candente). Quizás durante las pruebas descubra que Apollo no es adecuado para usted, o que le incomodan escribir pruebas unitarias basadas en este sistema de gestión de estado. No hay problema: escriba una nueva fachada diseñada para admitir MobX e intente el sistema nuevamente.


Los diferentes sistemas para administrar el estado de la aplicación, a los que se accede a través de una sola fachada, también pueden ser dragones ...

Resumen


Probablemente notó que cuando hablamos de patrones de diseño, no consideramos ejemplos de código. El hecho es que un análisis profundo de cada patrón dibuja al menos un capítulo separado en el libro más alejado del más delgado. Por cierto, ya que estamos hablando de libros, aquí tenemos publicaciones interesantes que puede consultar para aquellos que quieran profundizar en el estudio de patrones.

Al final, quiero decir que en el desarrollo de patrones, nada supera una búsqueda en Internet, leer y probar de forma independiente varias ideas. Incluso si resulta que nunca usará patrones, comprenderá algo nuevo y aprenderá sobre ellos y crecerá en áreas que son inesperadas para usted.

Estimados lectores! ¿Qué patrones de diseño usas?

Source: https://habr.com/ru/post/450318/


All Articles