Patrones de Diseño: Patrón singleton (Página 2)

Los singleton son clases de las que se puede crear una instancia una vez y a las que se puede acceder globalmente. Esta instancia única se puede compartir en toda nuestra aplicación, lo que hace que Singletons sea excelente para administrar el estado global en una aplicación.

Primero, echemos un vistazo a cómo puede verse un singleton usando una clase ES2015. Para este ejemplo, vamos a construir una clase Counter que tenga:

  • un método getInstance que devuelve el valor de la instancia
  • un método getCount que devuelve el valor actual de la counter variable
  • un método increment que incrementa el valor de counter en uno
  • un método decrement que disminuye el valor de counter en uno
let counter = 0;
class Counter {
getInstance() {
return this;
}
getCount() {
return counter;
}
increment() {
return ++counter;
}
decrement() {
return --counter;
}
}

Sin embargo, ¡esta clase no cumple con los criterios para un Singleton! Un Singleton solo debería poder crear una instancia una vez. Actualmente, podemos crear múltiples instancias de la clase Counter .

let counter = 0;
class Counter {
getInstance() {
return this;
}
getCount() {
return counter;
}
increment() {
return ++counter;
}
decrement() {
return --counter;
}
}
const counter1 = new Counter();
const counter2 = new Counter();
console.log(counter1.getInstance() === counter2.getInstance()); // false

Al llamar al método new dos veces, simplemente configuramos counter1 e counter2 e igualamos a diferentes instancias. Los valores devueltos por el getInstance método counter1 y counter2 efectivamente devolvieron referencias a diferentes instancias: ¡no son estrictamente iguales!

Asegurémonos de que solo se pueda crear una instancia de la clase. Counter

Una forma de asegurarse de que solo se pueda crear una instancia es creando una variable llamada instance . En el constructor de Counter , podemos establecer instance igual a una referencia a la instancia cuando se crea una nueva instancia. Podemos evitar nuevas instancias comprobando si la variable instance ya tenía un valor. Si ese es el caso, ya existe una instancia. Esto no debería suceder: debería aparecer un error para informar al usuario

let instance;
let counter = 0;
class Counter {
constructor() {
if (instance) {
throw new Error("You can only create one instance!");
}
instance = this;
}
getInstance() {
return this;
}
getCount() {
return counter;
}
increment() {
return ++counter;
}
decrement() {
return --counter;
}
}
const counter1 = new Counter();
const counter2 = new Counter();
// Error: You can only create one instance!

¡Perfecto! Ya no podemos crear varias instancias.

Exportemos la instancia Counter desde el archivo counter.js . Pero antes de hacerlo, también deberíamos congelar la instancia. El método Object.freeze garantiza que el código consumidor no pueda modificar el Singleton.

Las propiedades de la instancia congelada no se pueden agregar ni modificar, lo que reduce el riesgo de sobrescribir accidentalmente los valores en Singleton.

let instance;
let counter = 0;
class Counter {
constructor() {
if (instance) {
throw new Error("You can only create one instance!");
}
instance = this;
}
getInstance() {
return this;
}
getCount() {
return counter;
}
increment() {
return ++counter;
}
decrement() {
return --counter;
}
}
const singletonCounter = Object.freeze(new Counter());
export default singletonCounter;

Echemos un vistazo a una aplicación que implementa el Counter ejemplo. Disponemos de los siguientes archivos:

  • counter.js : contiene la clase Counter y exporta una instancia ** Counter como su exportación predeterminada
  • index.js : carga los módulos redButton.js y blueButton.js
  • redButton.js : importa Counter y agrega Counter el método increment como detector de eventos al botón rojo y registra el valor actual de counter invocando el método getCount
  • blueButton.js : importa Counter y agrega Counter el increment método como detector de eventos al botón azul y registra el valor actual de counter invocando el método getCount

Ambos blueButton.js e redButton.js importar la misma instancia desde counter.js . Esta instancia se importa como Counter en ambos archivos.

Cuando invocamos el método increment en redButton.js o blueButton.js , el valor de la propiedad counter en la instancia Counter se actualiza en ambos archivos. No importa si pulsamos en el botón rojo o en el azul: el mismo valor se comparte entre todas las instancias. Es por eso que el contador sigue incrementándose en uno, aunque estemos invocando el método en archivos diferentes.


Compensaciones

Restringir la creación de instancias a una sola instancia podría ahorrar mucho espacio en la memoria. En lugar de tener que configurar la memoria para una nueva instancia cada vez, solo tenemos que configurar la memoria para esa instancia, a la que se hace referencia en toda la aplicación. Sin embargo, los Singleton en realidad se consideran un antipatrón y pueden (o… deberían ) evitarse en JavaScript.

En muchos lenguajes de programación, como Java o C++, no es posible crear objetos directamente como lo hacemos en JavaScript. En esos lenguajes de programación orientados a objetos, necesitamos crear una clase, que crea un objeto. Ese objeto creado tiene el valor de la instancia de la clase, tal como el valor de instance en el ejemplo de JavaScript.

Sin embargo, la implementación de la clase que se muestra en los ejemplos anteriores es en realidad excesiva. Dado que podemos crear objetos directamente en JavaScript, simplemente podemos usar un objeto normal para lograr exactamente el mismo resultado. ¡Veamos algunas de las desventajas de usar Singletons!

Usando un objeto normal

Usemos el mismo ejemplo que vimos anteriormente. Sin embargo, esta vez, counter es simplemente un objeto que contiene:

  • una count propiedad
  • un increment método que incrementa el valor de count en uno
  • un decrement método que disminuye el valor de count en uno

Dado que los objetos se pasan por referencia, ambos redButton.js y blueButton.js importan una referencia al mismo counter objeto. Modificar el valor de count en cualquiera de estos archivos modificará el valor en counter , que es visible en ambos archivos.

Pruebas

Probar código que se basa en un Singleton puede resultar complicado. Como no podemos crear nuevas instancias cada vez, todas las pruebas se basan en la modificación de la instancia global de la prueba anterior. El orden de las pruebas es importante en este caso, y una pequeña modificación puede provocar que todo un conjunto de pruebas falle. Después de la prueba, debemos restablecer toda la instancia para restablecer las modificaciones realizadas por las pruebas.

Ocultación de dependencia

Al importar otro módulo, superCounter.js en este caso, puede que no sea obvio que el módulo está importando un Singleton. En otros archivos, como index.js en este caso, es posible que estemos importando ese módulo e invocando sus métodos. De esta manera, modificamos accidentalmente los valores en el Singleton. Esto puede provocar un comportamiento inesperado, ya que se pueden compartir varias instancias de Singleton en toda la aplicación, todas las cuales también se modificarían.

Comportamiento global

Se debería poder hacer referencia a una instancia Singleton en toda la aplicación. Las variables globales esencialmente muestran el mismo comportamiento: dado que las variables globales están disponibles en el ámbito global, podemos acceder a esas variables en toda la aplicación.

Tener variables globales generalmente se considera una mala decisión de diseño. La contaminación del alcance global puede terminar sobrescribiendo accidentalmente el valor de una variable global, lo que puede generar muchos comportamientos inesperados.

En ES2015, la creación de variables globales es bastante poco común. La palabra clave new let y const evita que los desarrolladores contaminen accidentalmente el alcance global, al mantener las variables declaradas con estas dos palabras clave en el ámbito de bloque. El nuevo module sistema en JavaScript facilita la creación de valores accesibles globalmente sin contaminar el alcance global, al poder almacenar export valores de un módulo y import esos valores en otros archivos.

Sin embargo, el caso de uso común de un Singleton es tener algún tipo de estado global en toda su aplicación. Hacer que varias partes de su código base dependan del mismo objeto mutable puede provocar un comportamiento inesperado.

Por lo general, ciertas partes del código base modifican los valores dentro del estado global, mientras que otras consumen esos datos. El orden de ejecución aquí es importante: ¡no queremos consumir datos accidentalmente primero, cuando no hay datos para consumir (todavía)! Comprender el flujo de datos cuando se utiliza un estado global puede resultar muy complicado a medida que la aplicación crece y docenas de componentes dependen unos de otros.

Gestión de estados en React

En React, a menudo confiamos en un estado global a través de herramientas de administración de estado como Redux o React Context en lugar de usar Singletons. Aunque su comportamiento de estado global puede parecer similar al de Singleton, estas herramientas proporcionan un estado de solo lectura en lugar del estado mutable de Singleton. Cuando se usa Redux, solo los reductores de funciones puras pueden actualizar el estado, después de que un componente haya enviado una acción a través de un despachador .

Aunque las desventajas de tener un estado global no desaparecen mágicamente al usar estas herramientas, al menos podemos asegurarnos de que el estado global cambie de la manera que pretendemos, ya que los componentes no pueden actualizar el estado directamente.


Relacionado

ForEach de Javascript: Array para bucles

Como una de las estructuras de control básicas en la programación, los bucles son casi una adición diaria al código que escribimos. El bucle forEach clásico es uno de los primeros fragmentos de código que aprendemos a escribir como programadores. Si fueras un desarrollador de Javascript, sabrías que Javascript no es ajeno a la iteración a través de los elementos de una matriz o un mapa ¡SEGUIR LEYENDO!

10 Mejores alternativas de Sci-hub para descargar artículos de investigación gratis

Como sabemos, Sci-hub es un sitio web increíble con millones de artículos de investigación para todos los estudiantes universitarios y académicos. El sitio web de Sci-Hub se encarga de obtener los artículos de investigación y artículos de pago utilizando las credenciales que se filtran. La fuente de credenciales utilizada por este sitio web no está clara. Sin embargo, se supone que muchas de ellas son donadas, ¡SEGUIR LEYENDO!

10 Características Sorprendentes de Windows que Deberías Conocer en 2024

Aunque haya sido usuario de Windows durante décadas, el sistema operativo es tan amplio y complejo que siempre existen características útiles, pero menos conocidas, que podrían sorprenderte. En este sentido, he identificado diez funciones poco conocidas de Windows que pueden potenciar su eficiencia, comodidad e incluso su experiencia de uso lúdico en su PC.

Microsoft Surface Go 2 - Portátil 2 en 1 de 10.5 pulgadas Full HD, Wifi, Intel...
  • Procesador Dual-Core Intel Pentium Gold 4425Y (2...
  • Memoria RAM de 8 GB LPDDR3
  • Disco SSD de 128 GB
Todas estas características deberían ser compatibles tanto con Windows 10 ¡SEGUIR LEYENDO!

10 Criptomonedas con Potencial de Crecimiento de Futuro

El rumor en torno a las criptomonedas no se desvanece por mucho que existan grandes pesimistas alrededor de los malos rumores. Entonces, si consideras invertir en el mundo de las criptomonedas, deberías estar atento a las criptomonedas que se espera que tengan un buen desempeño para el resto de 2021. En los últimos tiempos, los tokens DeFi están recibiendo toda la atención y es más que ¡SEGUIR LEYENDO!

10 Empresas de robótica más importantes del mundo

Los cambios de paradigma revolucionarios debido a los desarrollos de la robótica en todo el mundo están generando nuevos puntos de vista en muchos sectores, entre ellos en los de la industria y la tecnología. Con la ayuda de la Inteligencia Artificial, la tecnología produce resultados innovadores cada segundo y el campo de la robótica define y reconfigura su uso a cada instante. Cada día que ¡SEGUIR LEYENDO!

10 Frameworks que los Desarrolladores de Software deberían Aprender 2024

Bienvenidos desarrolladores web y de software, estamos en los inicios de 2023 y es posible que muchos se esten planteado sus objetivos para lo largo del año. Con anterioridad ya he compartidos las rutas de aprendizaje para un desarrollador front-end, un desarrollador full-stack o un desarrollador back-end entre otros muchos contenidos más. En este artículo, me gustaría compartir algunos de los mejores frameworks y bibliotecas para ¡SEGUIR LEYENDO!

10 Repositorio de GitHub que todo Desarrollador Web debería conocer

GitHub es el lugar que debes buscar cuando intentas mejorar como desarrollador, toda la información que necesitas está disponible en algún repositorio que alguien ya se ha molestado en indexar. Sin embargo, la parte complicado es encontrar el repositorio más adecuado. Es fácil sentirse perdido en todos los repositorios disponibles dentro de GitHub. Para ayudarte, he elaborado una lista de 10 repositorios de GitHub que pueden ¡SEGUIR LEYENDO!

10 Mejores billeteras sin custodia

Si se quiere lograr que DeFi tenga éxito, es crucial que las puertas de enlace para interactuar con la web 3 sean intuitivas, seguras y accesibles, manteniendo el espíritu central de ser el banco del futuro. En los últimos años, hemos visto mejoras drásticas en las carteras y otras herramientas de gestión de activos, lo que permite a los inversores y usuarios acceder de forma segura ¡SEGUIR LEYENDO!

21 Mejores Frameworks de Java

Si recién comienzas a programar con Java, puedes oje la guía para principiantes sobre Java que te guiará a través de todos los conceptos más importantes de Java que necesitas conocer, si pronto quieres comenzar a utilizar cualquier de los frameworks Java. Java es un lenguaje robusto y combinado con un framework Java, puede proporcionar las mejores soluciones para cualquier campo tecnológico, ya bien sea; un ¡SEGUIR LEYENDO!

11 Mejores Herramientas de Automatización de Pruebas para Interfaces de Usuario

¿Eres un profesional del testing y las pruebas de software? Si es así, ¿Qué herramienta de pruebas utilizas? Como la mayoría de las personas cuando comienzan en el control de calidad. es posible que tenga que dominar solo una o dos herramientas de prueba porque estás restringido a lo que estás utilizando en la empresa. Cualquiera que sea la razón, si usted es un profesional experimentado, ¡SEGUIR LEYENDO!

10 Mejores robots amigos que aparecen en películas (incluido Jeff de Finch)

Como demuestra la nueva película Finch de Apple+, los robots son excelentes amigos y hay bastantes memorables que aparecen en numerosas películas. 1. Baymax (Big Hero 6) Al igual que Pixar, Disney tiene la capacidad de crear personajes no humanos que sin embargo, tienen una gran cantidad de carisma y personalidad. Baymax, uno de los personajes principales de la película Big Hero 6 , es un ¡SEGUIR LEYENDO!