No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

15 Días
0 Hrs
8 Min
55 Seg

Implementación de Singleton en JS

4/27
Recursos

Aportes 17

Preguntas 1

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

 class Singleton {
    static instance = undefined; //Atributo estático para almacenar el valor, llamado para la validación de getInstance() 

    constructor(version) {
        this.version = version;
    }

    static getInstance(version) {
        //Si no existe el atributo instance...
        if (!Singleton.instance) {
            Singleton.instance = new Singleton(version); //...lo crea. 
        }
        return Singleton.instance;
    }

}

function appSingleton() {
    //Todas las variables tienen la misma referencia al mismo objeto. 1 sola instancia a lo largo de la aplicación:
    const singleton1 = Singleton.getInstance('version-1')
    const singleton2 = Singleton.getInstance('version-2')
    const singleton3 = Singleton.getInstance('version-3')

    console.log(singleton1 === singleton2); //true
    console.log(singleton1 === singleton3); //true
}
appSingleton();

Técnica para evitar el uso de new Singleton:

class Singleton {
	constructor() {
		throw new Error('No constructor in this house!')
	}
}

Pseudocódigo:


.

Diagrama:

Les dejo el Singleton en Java

Para los que les gusta TS como a mi, aqui el code adaptado:

class Singleton {
    static instance : Singleton | undefined;
    version:string

    constructor(version: string){
        this.version = version;
    }

    static getInstance(version:string){
        if(!Singleton.instance){
            Singleton.instance = new Singleton(version);
        }

        return Singleton.instance;
    }
}

function appSingleton() {
    //Todas las variables tienen la misma referencia al mismo objeto. 1 sola instancia a lo largo de la aplicación:
    const singleton1 = Singleton.getInstance('version-1')
    const singleton2 = Singleton.getInstance('version-2')
    const singleton3 = Singleton.getInstance('version-3')

    console.log(singleton1)
    console.log(singleton2)
    console.log(singleton3)

    console.log(singleton1 === singleton2); //true
    console.log(singleton1 === singleton3); //true
}
appSingleton();
Creo que por cuestiones didacticas seria mas conveniente empezar con los ejemplos y a partir de ahi ir identificando cada concepto, debido a que es mas dificil comprender los conceptos desde la abstraccion. En el mundo real, para llegar a los patrones de diseno primero se dan los casos de uso y luego se identifican los patrones y crean los conceptos a partir de las ocurrencias repetidas. Creo que seria valiosa esta metodologia para los cursos de programacion en general.

Algo interesante es que al leer el valor de version de las todas las instancias, el valor siempre será el de la primera instancia que se ha creado. En este caso “version-1”.

function appSingleton() {
  const singleton1 = Singleton.getInstance("version-1");
  const singleton2 = Singleton.getInstance("version-2");
  const singleton3 = Singleton.getInstance("version-3");

  console.log(singleton1 === singleton2);
  console.log(singleton1 === singleton3);
  console.log(singleton3.version); // version-1
}
Así fue como lo había aprendido a hacerlo ```js class Singleton{ static instance = undefined constructor(version){ if(Singleton.instance){ return Singleton.instance } this.version = version Singleton.instance = this } } ```class Singleton{    static instance = undefined    constructor(*version*){        if(Singleton.instance){           return Singleton.instance         }        this.version = *version*        Singleton.instance = this    }}con
Este patrón de diseño lo estuve utilizando sin saber que así se llamaba, creé una instancia para usar `remote-config` en un proyecto y funciona muy bien, no he visto a ninguno de mis colaboradores si quiera intentar usar el `new()` Me alegra poder conocer la teoría detrás de ello y poder argumentar su uso.

Diagrama del patrón Singleton.

  1. Hacer que el constructor sea privado.
  2. Crear un método estático que llame al constructor privado, internamente, y que guarde la instancia en una variable estática.
Además de la forma explicada por el Profesor Daniel en la clase acerca de cómo crear un Singleton en Javascript y siempre retornar la instancia "guardada en caché" mediante el método getInstance... Encontré este videíto super interesante en donde se implementa otra forma de hacerlo directamente con el mismo constructor ✨. <https://www.youtube.com/watch?v=rrWRhrdwuLg> En el video, en vez de crear un método "getInstance" que siempre nos retorne la instancia de la clase, directamente se modifica el constructor de la clase para que cada vez que se utilice el operador new para crear una nueva instancia; en vez de que se cree una nueva, retorne en cambio la única instancia que existe "guardada en caché" (y si no existe ninguna guardad previamente, entonces sí la crea). Es muy interesante ✨. Si bien este método se "salta las reglas" ya que no hace que el constructor sea privado ni tampoco crea un método estático getInstance... Logra el mismo comportamiento al modificar la forma en la que se usa el constructor. ¡Y eso me parece super genial!
Desde ES2022 Javascript soporta de manera nativa el uso de propiedades y métodos privados ✨. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_properties> Se definen con el # delante del nombre de la propiedad o método que se quiere que sea privada.
Aqui os dejo otro ejemplo para entender mejor el patron de diseño Singleton: ```js class Configuracion { // Variable estática que contendrá la única instancia static datos = undefined; // Constructor privado para inicializar la configuración (tema, idioma) constructor() { this.tema = "light"; // Tema predeterminado this.idioma = "es"; // Idioma predeterminado } // Método estático para obtener la instancia única de Configuracion static obtenerInstancia() { if (!Configuracion.datos) { Configuracion.datos = new Configuracion(); } return Configuracion.datos; } // Método para cambiar el tema cambiarTema(nuevoTema) { this.tema = nuevoTema; console.log(`Tema cambiado a: ${this.tema}`); } // Método para cambiar el idioma cambiarIdioma(nuevoIdioma) { this.idioma = nuevoIdioma; console.log(`Idioma cambiado a: ${this.idioma}`); } } function appConfiguracion() { console.log("--- Inicializando Configuración Global ---"); // Obtenemos la instancia única de Configuración const configuracion1 = Configuracion.obtenerInstancia(); configuracion1.cambiarTema("Oscuro"); configuracion1.cambiarIdioma("Esp"); // Obtenemos otra vez la instancia para poder ver que los valores de config no han cambiado y se mantienen iguales const configuracion2 = Configuracion.obtenerInstancia(); // Comprobamos si ambas instancias son iguales console.log(`¿Configuración1 y Configuración2 son la misma instancia? ${configuracion1 === configuracion2 ? "Sí" : "No"}`); // Imprimimos los valores para comprobar que ambos acceden a la misma configuración console.log(`Configuración1 tema: ${configuracion1.tema}`); console.log(`Configuración2 tema: ${configuracion2.tema}`); console.log(`Configuración1 idioma: ${configuracion1.idioma}`); console.log(`Configuración2 idioma: ${configuracion2.idioma}`); } appConfiguracion(); ```
### Razones para Evitar la Lógica Singleton en el Constructor He visto en algunos ejemplos por internet, donde evitan usar el método getInstance() e implementan la logical del patron en el constructor de la clase, pero dejo algunas razones para no hacerlo. 1. Viola el Propósito del Constructor: * Los constructores están diseñados para inicializar nuevas instancias de una clase, no para controlar la cantidad de instancias o administrar la lógica de acceso a ellas. * Si incluyes la lógica del Singleton en el constructor, estás sobrecargando su propósito, lo que puede llevar a confusión y malas prácticas de diseño. 2. Dificulta el Control de Acceso: * El patrón Singleton funciona porque controla la creación de la instancia desde un método estático (`getInstance()`), manteniendo el constructor privado para que no se pueda acceder directamente desde fuera de la clase. * Si la lógica de creación se encuentra en el constructor, no se puede evitar que alguien intente crear una instancia usando `new`, lo que rompe el patrón. 3. Problemas de Mantenimiento y Claridad: * Mantener la lógica en el método `getInstance()` hace que sea más claro para cualquier desarrollador que lea tu código que esa es la única forma permitida de crear una instancia de la clase. * Dejar esta lógica en el constructor puede confundir, especialmente si el constructor sigue siendo accesible o no se maneja correctamente su visibilidad.
Implementación de Singleton en TS ```js class Singleton { private static instance: Singleton; // Hacer el constructor privado para prevenir la instanciación directa. private constructor() { console.log('Instancia creada'); } // Método estático para obtener la instancia única. public static getInstance(): Singleton { // Si la instancia no existe, la creamos. if (!Singleton.instance) { Singleton.instance = new Singleton(); } // Retornamos la instancia única. return Singleton.instance; } // Un método de ejemplo para la instancia. public someMethod(): void { console.log('Método de la instancia Singleton'); } } // Uso del Singleton const singleton1 = Singleton.getInstance(); const singleton2 = Singleton.getInstance(); singleton1.someMethod(); // Imprime: "Método de la instancia Singleton" // Comprobación de que ambas referencias apuntan a la misma instancia. console.log(singleton1 === singleton2); // Imprime: true ```class Singleton { ==================== # private static instance: Singleton; // Hacer el constructor privado para prevenir la instanciación directa. private constructor() { console.log('Instancia creada'); } // Método estático para obtener la instancia única. public static getInstance(): Singleton { // Si la instancia no existe, la creamos. if (!Singleton.instance) { Singleton.instance = new Singleton(); } // Retornamos la instancia única. return Singleton.instance; } // Un método de ejemplo para la instancia. public someMethod(): void { console.log('Método de la instancia Singleton'); } } // Uso del Singleton const singleton1 = Singleton.getInstance(); const singleton2 = Singleton.getInstance(); singleton1.someMethod(); // Imprime: "Método de la instancia Singleton" // Comprobación de que ambas referencias apuntan a la misma instancia. console.log(singleton1 === singleton2); // Imprime: true
no entendi nada
🟡 Se podría usar además la variable instance como privada, para evitar su modificación? ```js class Singleton { static #instance = undefined constructor(version){ this.version = version } static getInstance(version) { if (!Singleton.#instance) { Singleton.#instance = new Singleton(version) } return Singleton.#instance } } function appSingleton() { const singleton1 = Singleton.getInstance('version1') const singleton2 = Singleton.getInstance('version2') console.log(singleton1 === singleton2) // true } appSingleton() ```*class* Singleton {    *static* #instance = *undefined*     constructor(*version*){        this.version = *version*    }     *static* getInstance(*version*) {        *if* (!Singleton.#instance) {            Singleton.#instance = new Singleton(*version*)        }         *return* Singleton.#instance    }} function appSingleton() {    const singleton1 = Singleton.getInstance('version1')    const singleton2 = Singleton.getInstance('version2')        console.log(singleton1 === singleton2) *// true*} appSingleton()