¿Cuál es la forma mejor y más conveniente de implementar un patrón Singleton para una clase en TypeScript? (Tanto con y sin inicialización perezosa).
singleton
typescript
maja
fuente
fuente
export default new Singleton()
?Desde TS 2.0, tenemos la capacidad de definir modificadores de visibilidad en los constructores , por lo que ahora podemos hacer singletons en TypeScript como estamos acostumbrados desde otros lenguajes.
Ejemplo dado:
Gracias @Drenai por señalar que si escribes código usando el javascript compilado sin procesar no tendrás protección contra la creación de instancias múltiples, ya que las restricciones de TS desaparecen y el constructor no estará oculto.
fuente
La mejor manera que he encontrado es:
Así es como lo usas:
https://codebelt.github.io/blog/typescript/typescript-singleton-pattern/
fuente
El siguiente enfoque crea una clase Singleton que puede usarse exactamente como una clase convencional:
Cada
new Singleton()
operación devolverá la misma instancia. Sin embargo, esto puede ser inesperado por el usuario.El siguiente ejemplo es más transparente para el usuario pero requiere un uso diferente:
Uso:
var obj = Singleton.getInstance();
fuente
new Class(...)
sintaxis.Me sorprende no ver el siguiente patrón aquí, que en realidad parece muy simple.
Uso
fuente
Shout
embargoPuede usar expresiones de clase para esto (a partir de 1.6, creo).
o con el nombre si su clase necesita acceder internamente a su tipo
Otra opción es usar una clase local dentro de su singleton usando algunos miembros estáticos
fuente
Agregue las siguientes 6 líneas a cualquier clase para que sea "Singleton".
Ejemplo de prueba:
[Editar]: use la respuesta de Alex si prefiere obtener la instancia a través de una propiedad en lugar de un método.
fuente
new MySingleton()
, digo 5 veces? ¿Su código reserva una sola instancia?creo que tal vez usar genéricos sea la masa
cómo utilizar
paso 1
paso 2
fuente
También puede hacer uso de la función Object.Freeze () . Es simple y fácil:
fuente
if (!this.instance)
el constructor? ¿Es solo una precaución adicional en caso de que haya creado varias instancias antes de la exportación?He encontrado una nueva versión de esto con la que el compilador deScript está totalmente de acuerdo, y creo que es mejor porque no requiere llamar a un
getInstance()
método constantemente.Esto viene con un inconveniente diferente. Si
Singleton
tiene propiedades, el compilador de Script mecanografiará un ajuste a menos que lo inicialice con un valor. Es por eso que incluí una_express
propiedad en mi clase de ejemplo porque a menos que la inicialice con un valor, incluso si la asigna más adelante en el constructor, TypeScript pensará que no se ha definido. Esto podría solucionarse desactivando el modo estricto, pero prefiero no hacerlo si es posible. También hay otro inconveniente de este método que debo señalar, porque en realidad se llama al constructor, cada vez que lo hace se crea técnicamente otra instancia, pero no es accesible. Esto podría, en teoría, causar pérdidas de memoria.fuente
Este es probablemente el proceso más largo para hacer un singleton en mecanografiado, pero en aplicaciones más grandes es el que mejor me ha funcionado.
Primero necesita una clase Singleton en, digamos, "./utils/Singleton.ts" :
Ahora imagine que necesita un enrutador singleton "./navigation/Router.ts" :
¡Agradable !, ahora inicialice o importe donde lo necesite:
Lo bueno de hacer singletons de esta manera es que todavía usas toda la belleza de las clases de mecanografía, te da un buen sentido, la lógica singleton se mantiene separada y es fácil de eliminar si es necesario.
fuente
Mi solución para ello:
fuente
return Modal._instance
. De esta manera, sinew
esa clase, obtienes el objeto existente, no uno nuevo.En Typecript, uno no necesariamente tiene que seguir la
new instance()
metodología Singleton. Una clase estática importada, sin constructor, puede funcionar igualmente.Considerar:
Puede importar la clase y consultarla
YourSingleton.doThing()
en cualquier otra clase. Pero recuerde, debido a que esta es una clase estática, no tiene constructor, por lo que generalmente uso unintialise()
método que se llama desde una clase que importa Singleton:No olvide que en una clase estática, todos los métodos y variables también deben ser estáticos, por lo que en lugar de
this
usar el nombre completo de la claseYourSingleton
.fuente
Aquí hay otra forma de hacerlo con un enfoque de JavaScript más convencional utilizando un IFFE :
Ver una demostración
fuente
Instance
variable? Podrías simplemente poner la variable y las funciones directamente debajoApp.Counter
.Otra opción es usar símbolos en su módulo. De esta manera, puede proteger su clase, también si el usuario final de su API está usando Javascript normal:
Uso:
Si el usuario está utilizando su archivo compilado API js, también recibirá un error si intenta crear una instancia manual de su clase:
fuente
No es un singleton puro (la inicialización puede no ser perezosa), sino un patrón similar con ayuda de
namespace
s.Acceso al objeto de Singleton:
fuente
Esta es la forma más sencilla
fuente
De esta manera podemos aplicar una interfaz, a diferencia de la respuesta aceptada de Ryan Cavanaugh.
fuente
Después de recorrer este hilo y jugar con todas las opciones anteriores, me decidí por un Singleton que se puede crear con los constructores adecuados:
Se requeriría una configuración inicial (in
main.ts
oindex.ts
), que puede implementarse fácilmente mediantenew Singleton(/* PARAMS */)
Luego, en cualquier parte de su código, simplemente llame
Singleton.instnace
; en este caso, parawork
terminar, llamaríaSingleton.instance.work()
fuente