Singleton es un patrón de diseño creacional que garantiza que una clase tenga una única instancia, al tiempo que proporciona un punto de acceso global a dicha instancia.
💡 Ver Caso Práctico: Ejemplo Práctico del Patrón Singleton
Propósito y Caso de Uso
Utiliza el patrón Singleton cuando una clase en tu programa deba tener una única instancia disponible para todos los clientes (por ejemplo, un objeto de conexión a base de datos, un logger centralizado o un gestor de configuración global).
Estructura del Patrón
Independientemente del lenguaje de programación (TypeScript, PHP, Python, C++, etc.), la estructura conceptual del patrón se basa en tres pilares:
- Constructor privado: Impide que otros objetos utilicen el operador
newdirectamente. - Atributo estático privado: Almacena la referencia a la instancia única creada.
- Método estático público (
getInstance): Actúa como punto de acceso global que inicializa la instancia la primera vez que se solicita y la retorna en subsecuentes llamadas.
Cargando diagrama...
Flujo de Funcionamiento
- Solicitud: El cliente llama a
Singleton.getInstance(). - Comprobación: La clase verifica si la variable estática
instanceya contiene un objeto instanciado. - Inicialización diferida o bajo demanda (Lazy initialization): Si la instancia no existe (
nulloundefined), invoca de forma privada el constructor y la asigna. - Devolución: Retorna la instancia existente, garantizando un único objeto compartido en toda la aplicación.
Ejemplos de Implementación Reales
// LoggerService.ts — Servicio de registro centralizado
class LoggerService {
private static instance: LoggerService;
private logs: string[] = [];
private constructor() {}
public static getInstance(): LoggerService {
if (!LoggerService.instance) {
LoggerService.instance = new LoggerService();
}
return LoggerService.instance;
}
public log(message: string): void {
const timestamp = new Date().toISOString();
const entry = `[${timestamp}] ${message}`;
this.logs.push(entry);
console.log(entry);
}
public getHistory(): string[] {
return [...this.logs];
}
}
// Uso en cualquier módulo de la aplicación:
const logger1 = LoggerService.getInstance();
logger1.log("Usuario inicio sesion");
const logger2 = LoggerService.getInstance();
logger2.log("Respuesta HTTP 200 recibida");
// Ambas referencias apuntan al mismo objeto e historial compartido
console.log(logger1 === logger2); // true