JavaScript de Cero a Experto / Patrones y observables
Singleton: el único ejemplar
Hay piezas de una app que DEBEN ser únicas: la configuración, la conexión al servidor, el carrito del usuario. Dos copias descoordinadas = bugs bizarros. El patrón singleton garantiza el ejemplar único — y en JavaScript moderno tiene un secreto encantador: los módulos ya te lo regalan.
El acueducto del barrio
El singleton gratis: un módulo con estado
La lección pasada lo dejó dicho: un módulo se evalúa UNA vez y se cachea — todos los que lo importan comparten LO MISMO. Entonces un singleton en JavaScript moderno es simplemente… un módulo que exporta la instancia:
Sigue la prueba: pantalla-a y pantalla-b importan sesion.js cada una
por su lado… y el log de construcción sale UNA vez, y el cambio que hace A
lo ve B. No hay dos sesiones: hay un acueducto y dos llaves. Este patrón —
módulo con estado privado + funciones de acceso exportadas — es el
singleton idiomático de JavaScript, y lo usarás para configuración,
cachés, el cliente de tu API…
La versión con clase (la verás por ahí)
Antes de ESM, el patrón se hacía a mano con una clase que se guarda a sí misma:
class Sesion {
static #instancia = null; // el único ejemplar, guardado en el molde
static obtener() {
if (Sesion.#instancia === null) Sesion.#instancia = new Sesion();
return Sesion.#instancia; // siempre EL MISMO objeto
}
}
Sesion.obtener() === Sesion.obtener(); // trueLéela y admira las piezas del módulo 11 trabajando juntas (static + campo privado + construcción perezosa)… y luego guárdala como cultura: en código moderno, el módulo hace esto con cero ceremonia. Si te la piden en entrevista, la sabes escribir; en tu código, exporta desde un módulo.
Nota honesta de arquitecto: el singleton tiene mala fama merecida cuando se vuelve el cajón GLOBAL donde todo el mundo lee y escribe de todo — eso acopla la app entera a un punto y hace los tests un infierno (el módulo 16 te lo mostrará). Regla de oro: pocas cosas merecen ser únicas, y las que lo sean exponen una API mínima (funciones), no el objeto crudo mutable.
El archivo carrito.js exporta funciones sobre un array privado de productos. Lo importan la página de tienda y la de pago. ¿Cuántos carritos existen y por qué?
Mini-reto
Construye el singleton de "Mi Bolsillo": un bolsillo.js con array
privado de gastos y exports agregar(nombre, valor) (con validación que
lanza, módulo 11) y total(). Impórtalo desde dos módulos "pantalla" —
uno agrega, el otro consulta — y comprueba en index.js que ambos
trabajan sobre el mismo bolsillo. Remate mental: ¿qué exportarías (y qué
JAMÁS) para que nadie pueda meter un gasto sin validar?
Qué sigue
El singleton garantiza UN ejemplar. El patrón opuesto — fabricar MUCHOS, a pedido y con variantes — también tiene nombre: factory. Ya la usaste sin saberlo dos módulos seguidos; la próxima lección la formaliza y te da el criterio factory vs clase.