Contenido del curso
Contenido del curso
Carlos Andrés Jaramillo Villa
Bryan David Castañeda Aranzales
David Guevara
Miguel Angel Reyes Moreno
Gerardo Miranda
José Eras
mars Dev
Alex Maldonado
Luis Hernando Sendoya Serrato
Paola Alapizco
Gustavo Medina Limon
Eduardo Robles
Eder Ramirez
Jorge Aguilar
Luis Lazcano
Jesus Daniel Castro Flores
Brahyan Antonio Martinez Madera
Juan Castro
María Carolina Guerra Gil
Alejandro Sebastian Dubon Estrada
Álvaro Gabriel Soria Guzmán
David Rangel
Dario Mendoza
Álvaro Gabriel Soria Guzmán
Diego Raciel Ortega Hernandez
Ronaldo Delgado
Julian David Vidal González
Andre Huaman Yovera
Rafael Rodríguez Flores
brandon james grimaldo moscote
Carlos Alberto De Avila Suro
Alvaro Andrade
Adriana Paredes Salinas
se me hace extranio entender en que forma sera util (se nota que falta mucha experiecia). pero se ve interesante!.
Tranquilo jajaja no eres el unico compa, he visto varios patrones de diseño y tampoco les encuentro una utilidad pero por algo las empresas lo deben de pedir, yo digo que es para casos muy especificos o para argumentar la solucion efectiva de un problema.
Hola, por ejemplo para una Clase maneja la conexión a una base de datos. Imagina que quieres tener solo 100 conexiones disponibles y estas se crean cuando se crean la instancia de la clase la primera vez. _ Podría pasar que si creas una nueva instancia de la clase se crean 100 conexiones mas ( buscar productos 100 + editar producto 100 …) hasta que la base de datos deje de responder. _ Otra cosa interesante es que los objetos ocupan memoria ram y podrías estar creando objetos muy grandes muchas veces innecesariamente y quedarte si memoria ram y que la app muera.
¡Qué interesante! :o
Singleton: constructor privado
Singleton nos previene crear múltiples instancias de una clase.
Esto es muy usado en Arquitectura de Software, pues nos ayuda a ahorrar uso de memoria.
export class MyService { static instance: MyService | null = null; private constructor( private name: string ) {} get Name() { return this.name; } static create(name: string) { if (MyService.instance === null) { console.log('Creating new instance'); MyService.instance = new MyService(name); } return MyService.instance; } } const myService1 = MyService.create('MyService1'); console.log(myService1.Name) const myService2 = MyService.create('MyService2'); console.log(myService2.Name) const myService3 = MyService.create('MyService3'); console.log(myService3.Name) console.log(myService1 === myService2); //* true console.log(myService1 === myService3); //* true
la propiedad instace no debería se private para que no se pueda acceder a ella directamente desde fuera?
Sí, debería.
Es lo mismo que me estaba preguntando jaja
Propósito
Singleton es un patrón de diseño creacional que nos permite asegurarnos de que una clase tenga una única instancia, a la vez que proporciona un punto de acceso global a dicha instancia.
https://refactoring.guru/es/design-patterns/singleton
Aquí un archivo interesante para aprender sobre este patrón de diseño
:computer: Para aquellos que quieran ir un poco más allá y entender mejor que es, como funciona, porque usar o no usar este patron de diseño, les dejo este enlace a un video de BettaTech donde lo explica a mayor detalle. . :movie_camera: Acá una lista de reproducción con más patrones de diseño . Espero este aporte les sea de ayuda :D
Buen aporte compañera, gracias!
no es posible hacer este patron sin typescript?
si se puede, de hecho es un patron que se puede implementar en cualquier lenguaje. Yo lo he implementado en Java programando para android
Se puede en TODOS los lenguajes de programación con el que estés trabajando el POO!!. Es un patrón de diseño!. no una característica del lenguaje.
Además de crear un Singleton esto también hace que la Clase sea final. Una palabra reservada en lenguajes como Java que no permite la herencia. ¿Por que necesitarías eso? Uno de los principios de diseño es Composición sobre Herencia!
por qué se menciona que es un antipatron en este hilo de StackOverflow?
No es facil de plasmar pero son varias consideraciones :
No es necesario (No literalmente XD): En JavaScript, es fácil crear una variable global y acceder a ella desde cualquier lugar del código, por lo que no es necesario utilizar el patrón Singleton para proporcionar un acceso global a una instancia de una clase.
Dificulta la prueba: Si una clase es un Singleton, es difícil probarla de manera aislada, ya que siempre está vinculada a su única instancia. Esto puede hacer que sea más difícil escribir pruebas unitarias para la clase y puede dificultar la depuración de problemas.
Dificulta la escalabilidad: Si una clase es un Singleton, es difícil escribir código que dependa de ella de manera fácilmente reutilizable, ya que siempre está vinculada a su única instancia. Esto puede dificultar la escalabilidad del código a medida que se agreguen más funcionalidades.
Puede ser confuso: El patrón Singleton puede ser confuso para los desarrolladores que no están familiarizados con él, ya que puede no ser evidente que una clase es un Singleton y cómo se puede acceder a su única instancia.
En resumen, el patrón Singleton puede ser útil en algunos casos, pero en general es considerado un antipatrón en JavaScript y TypeScript debido a que puede dificultar la prueba, la escalabilidad y la legibilidad del código. Es mejor evitar su uso a menos que sea absolutamente necesario aunque la verdad es mejor saber que no saber XD, si llegaste hasta aca, gracias por leer todo GG 💙
Creo que esta clase te puede interesar: https://platzi.com/clases/6933-patrones-diseno-creacionales/60865-singleton-pros-y-contras/
Si quieres aprender un poco más sobre patrones de diseño te dejo este recurso que me pareció genial:
Esta clase estuvo muy buena, el patrón singleton nos sirve para crear una única instancia de algún objeto en específico... por ejemplo podemos gestionar conexiones a bases de datos.
¿Por qué se debe crear una sola instancia de una clase? tenía entendido que una clase es como un sello con el que se puede crear varios (estampas) objetos de dicha clase
Pues mira, un Singleton solía ser una forma de compartir datos o información entre componentes.
Por ejemplo, para una tienda en línea un Singleton servía para que al darle click a un producto, este le comunicara al carrito de compras y a la pasarela de pagos que seleccionaste "x" cantidad de "x" producto y que esta información persistiera aunque te cambiarias de sección, de página, etc, y todos te dirían que seleccionaste exactamente 3 productos de exactamente el "producto x".
Sin el Singleton no podrías comunicar esto o, si el singleton no fuera de una sola instancia, la página podría decir (con números inventados) que tienes 3 productos seleccionados de "producto y", el carrito podría decir que tienes 7 del "producto n" y la pasarela de pagos podría decir que tienes 1 del "producto y", porque no habría una fuente de verdad y podría cambiar la data por un cálculo, función intermedia, etc.
En React, el Singleton fue sustituido por el useState y los Context (Consumer y Provider), pues los Singletons aún con lo buenos que son pueden fallar.
En un proyecto real, un proveedor de por ejemplo servicios de autenticación, te podría decir que para usar su software tienes que conectarte a su api con ciertas keys y para poder usar su tecnología en tu software podrías usar instancias de las clases que proveen en su documentación, y estas clases pueden ser Singletons para tener consistencia en los datos.
El patrón Singleton es un patrón de diseño que restringe la instanciación de una clase a un solo objeto. Esto es útil cuando se necesita exactamente un objeto para coordinar acciones a través del sistema. En programación orientada a objetos, este patrón asegura que una clase tenga una única instancia y proporciona un punto de acceso global a ella. En TypeScript, puedes implementar este patrón utilizando una propiedad estática que contenga la instancia y un constructor privado para evitar instancias externas.
¡Gracias, que útil aclaración!
Ya veo por que la gente dice que los patrones de diseño diferencian a un junior de un senior
Me gustaría ver un ejemplo mas practico de este tema
Veo la utilidad cuando se trabaja con bases de datos, por ejem tienes varios modulos (archivos .ts) en los que necesitas interactuar con una base de datos, si te conectas a la misma base de datos desde cada modulo, va a haber un delay y puede producir bugs, con singleton, si te contectas a la base de datos una vez, siempre vas a usar la misma conexión no importa si llamas la funcion "connect" mas de una vez en diferentes modulos.
En TypeScript, el patrón Singleton se utiliza para asegurarse de que solo exista una instancia de una clase en todo el programa. Esto es útil cuando necesitas tener acceso a un objeto único desde múltiples partes del código. . Aquí tienes un ejemplo de cómo implementar un Singleton en TypeScript con un constructor privado:
class Singleton { private static instance: Singleton; // La instancia única de la clase private constructor() { // El constructor privado evita la creación de instancias directamente } public static getInstance(): Singleton { if (!Singleton.instance) { Singleton.instance = new Singleton(); } return Singleton.instance; } public showMessage(): void { console.log("Soy una instancia de Singleton"); } } // Uso del Singleton const instance1 = Singleton.getInstance(); const instance2 = Singleton.getInstance(); console.log(instance1 === instance2); // true, ambas variables apuntan a la misma instancia instance1.showMessage(); // "Soy una instancia de Singleton" instance2.showMessage(); // "Soy una instancia de Singleton"
En este ejemplo, la clase Singleton tiene un constructor privado, lo que significa que no se puede crear una instancia directamente usando new Singleton(). En cambio, debemos utilizar el método estático getInstance() para obtener la instancia existente o crear una nueva si aún no existe.
.
Cuando llamamos a getInstance(), verificamos si la instancia ya existe. Si no existe, creamos una nueva instancia y la asignamos a la propiedad estática instance. Luego, devolvemos la instancia existente o recién creada.
.
Al utilizar el Singleton, podemos crear múltiples referencias a través de getInstance(), pero todas apuntarán a la misma instancia. Por eso, al comparar instance1 y instance2, obtenemos true. Además, ambas instancias pueden llamar al método showMessage() y mostrarán el mismo mensaje en la consola.
.
Espero que este ejemplo te haya ayudado a entender cómo se implementa un Singleton en TypeScript con un constructor privado. Si tienes alguna otra pregunta, no dudes en hacerla.
Realmente en un patrón de TypeScript y de muchos ostros lenguajes, es un patrón, una plantilla, una forma de crear código habitual con un fin. Aquí se ve cómo se hace con TS pero se usa en más leguanjes con implementación similar ;)
Esto es super útil, muy circunstancial pero super útil.
Los constructores privados no se suelen usar mucho, sin embargo hay un patrón que podemos aplicar haciendo uso de los constructores privados, ese patrón es Singleton, uno de los principios de la arquitectura Solid pero ¿De qué trata Singleton? Singleton garantiza que solo creemos una instancia de un objeto previniendo bloqueos de memoria y creación de muchas instancias de un solo objeto y además garantizando que solo tenemos un punto de acceso para esa instancia.
Cuando creamos una clase, normalmente la dotamos de un constructor de la siguiente manera
export class MyService {
constructor(private name:string){}
getName(){
return this.name
}
}
Si crearamos dos objetos a partir de esta misma clase
const myService1 = new MyService("entregaExpress")
console.log(myService1.getName())
const myService2 = new MyService("entrega pluss")
console.log(myService2.getName())
Obtendremos el siguiente resultado
entregaExpress
entrega plus
Si compararamos ambos objetos
console.log(myService1 === myService2)
El resultado sería
false
Lo cual significa que hemos creado dos objetos distintos
El propósito de Singleton es que cada vez que creemos un objeto a partir de una clase no se duplique sino que se use la instancia que previamente fué creada si es que lo fué y si no, se cree en ese momento, para ello usamos los constructores privados lo ilustramos modificando el ejemplo anterior.
Nuestro constructor quedaria de la siguiente manera private constructor(private name:string){}
De esta manera se restringe el constructor para que solo pueda ser usado dentro de la clase sometiendolo así a un control más riguroso
necesitaremos también una propiedad o variable estática con un valor inicial de null dentro de la clase la cual usaremos como bandera
static isService:MyService | null = null
Necesitaremos también un método estático que evalue el valor de la variable estatica (En nuestro caso isService) Si es nula se invoca el constructor para crear el objeto y asignarlo a la variable estatica misma que será devuelta con el nuevo objeto, si no fuera nula significa que ya se creo el objeto previamente y entonces solo la regresa con el objeto que previamente se le asignó
static creaServicio(name:string){
if(MyService.isService===null){
console.log("Esto solo se debe ejecutar una vez")
MyService.isService = new MyService(name)
}
return MyService.isService
}
El codigo completo de nuestra nueva clase quedaría así:
export class MyService {
static isService:MyService | null = null
private constructor(private name:string){}
static creaServicio(name:string){
if(MyService.isService===null){
console.log("Esto solo se debe ejecutar una vez")
MyService.isService = new MyService(name)
}
return MyService.isService
}
getName(){
return this.name
}
}
Entonces instanciamos el objeto a partir de nuestra clase
const myService1 = MyService.creaServicio("entregaExpress")
Al ejecutarlo por primera vez se crea el objeto y lo asigna a la variable myService1 si visualizamos su valor
console.log(myService1.getName())
obtendremos el nombre asignado
entregaExpress
Si repetimos el proceso como si fueramos a crear otro objeto de esta clase como el ejemplo de abajo
const myService2 = MyService.creaServicio("entrega pluss")
Nos percataremos de que como el objeto ya esta creado, no se vuelve a crear sino que ambas variables (myService1 y myService2 ) reciben el mismísimo objeto y lo podemos comprobar comparando ambas variables de la siguiente manera
console.log(myService1 === myService2)
Obtendremos true y ademas ya no se imprimira la siguiente linea
console.log("Esto solo se debe ejecutar una vez")
Con lo cual comprobamos que mediante este Singleton se pueden restringir las instancias de la clase.
Por que en la función create se utiliza MyService en lugar de this ?
static create(name: string) { if (MyService.instance === null) { MyService.instance = new MyService(name); } return MyService.instance; }
this no es la referencia a la clase ?
En la función create de la clase MyService, se utiliza MyService en lugar de this porque create es un método estático. Los métodos estáticos pertenecen a la clase en sí y no a instancias individuales de la clase. Por lo tanto, dentro de un método estático, no se puede hacer referencia a las propiedades o métodos de una instancia particular usando this.
En lugar de acceder a una instancia específica de la clase, los métodos estáticos generalmente se utilizan para realizar operaciones que son comunes a toda la clase o para crear instancias de la misma.