Abby's Digital Cafe

Patrón creaciónal - Singleton

¿Qué es el patrón Singleton?

El patrón de diseño Singleton pertenece al grupo de los patrones creacionales y su objetivo es garantizar que una clase tenga una única instancia en toda la aplicación, proporcionando un punto de acceso global a ella. Es especialmente útil cuando necesitamos centralizar el control sobre un recurso compartido, como una conexión a base de datos, un logger o una configuración global.

Su implementación suele incluir tres elementos clave:

  1. Un constructor privado que impide crear instancias desde fuera de la clase.
  2. Una propiedad estática que almacena la instancia única.
  3. Un método público estático (generalmente llamado getInstance()) que devuelve la instancia existente o la crea si no existe aún.

Ejemplo 1: Singleton en TypeScript (logger global)

Supongamos que tenemos un sistema que requiere un logger único para toda la aplicación. Queremos asegurarnos de que todos los módulos usen la misma instancia para mantener la coherencia de logs y timestamps.

[typescript]
class Logger { private static instance: Logger; private constructor() {} static getInstance(): Logger { if (!Logger.instance) { Logger.instance = new Logger(); console.log('Nueva instancia del logger creada'); } return Logger.instance; } log(message: string) { console.log(`[${new Date().toISOString()}] ${message}`); } } // Uso const logger1 = Logger.getInstance(); const logger2 = Logger.getInstance(); logger1.log('Inicializando aplicación...'); console.log('¿Es la misma instancia?', logger1 === logger2);

En este ejemplo, aunque llamemos getInstance() múltiples veces, solo se crea una instancia de Logger. Todas las llamadas posteriores usan la misma referencia, garantizando un registro coherente y un control centralizado.

Ejemplo 2: Singleton en Java (conexión a base de datos)

En aplicaciones empresariales Java, el patrón Singleton se usa frecuentemente para administrar recursos costosos, como conexiones a bases de datos o configuraciones compartidas. Veamos un ejemplo:

[java]
public class DatabaseConnection { private static DatabaseConnection instance; private Connection connection; private DatabaseConnection() { try { String url = "jdbc:mysql://localhost:3306/mi_bd"; String user = "root"; String password = "1234"; this.connection = DriverManager.getConnection(url, user, password); System.out.println("Conexión creada correctamente."); } catch (SQLException e) { e.printStackTrace(); } } public static synchronized DatabaseConnection getInstance() { if (instance == null) { instance = new DatabaseConnection(); } return instance; } public Connection getConnection() { return connection; } } // Uso DatabaseConnection db1 = DatabaseConnection.getInstance(); DatabaseConnection db2 = DatabaseConnection.getInstance(); System.out.println(db1 == db2); // true

El método getInstance() está sincronizado para evitar que múltiples hilos creen instancias diferentes en entornos multithreading. De esta forma, garantizamos una sola conexión compartida en toda la aplicación.


Preguntas frecuentes

¿Cuándo conviene usar un Singleton?

Cuando necesitas un único punto de acceso a un recurso global, como un servicio de logging, configuración, caché o conexión a base de datos. Sin embargo, evita usarlo como sustituto de un gestor de dependencias.

¿El Singleton rompe el principio de responsabilidad única?

Puede hacerlo si se usa mal. Un Singleton que comienza gestionando un recurso, pero termina almacenando configuraciones, métricas y estados globales, está violando el principio SRP (Single Responsibility Principle).

¿Cómo testear clases que dependen de un Singleton?

Una opción es inyectar el Singleton como dependencia (Dependency Injection) o proveer un método para reemplazar la instancia en entornos de test. Otra alternativa es usar un patrón alternativo como el Service Locator o Factory Method.


En resumen, el patrón Singleton es una herramienta poderosa para controlar instancias únicas, pero debe aplicarse con cuidado. Usado correctamente, puede optimizar recursos y simplificar la gestión de servicios globales; mal aplicado, puede generar acoplamiento y dificultar las pruebas.

Comentarios