Problema
Garantizar que una clase tenga solo una instancia y proporcionar un punto de acceso global a ella.
Propósito
Controlar la instanciación de una clase para asegurar que solo exista un objeto de esa clase en todo el sistema, proporcionando acceso global a esa instancia única.
Casos de uso comunes
- Loggers del sistema
- Configuraciones de aplicación
- Conexiones a base de datos
- Caches globales
- Pools de recursos
- Managers de estado global
Diagrama
classDiagram
class Singleton {
-static instance: Singleton
-Singleton()
+static getInstance() Singleton
+doSomething()
}
class Client1 {
+useService()
}
class Client2 {
+useService()
}
Client1 --> Singleton : getInstance()
Client2 --> Singleton : getInstance()
note for Singleton "Solo una instancia <br> existe en el sistema"
Flujo de creación
sequenceDiagram
participant Client1
participant Client2
participant Singleton
Client1->>Singleton: getInstance()
alt Primera llamada
Singleton->>Singleton: crear instancia
Singleton-->>Client1: retorna nueva instancia
end
Client2->>Singleton: getInstance()
alt Llamadas posteriores
Singleton-->>Client2: retorna instancia existente
end
Note over Client1,Client2: Ambos clientes usan la misma instancia
Ventajas
- Instancia única: Garantiza una sola instancia en el sistema
- Acceso global: Punto de acceso controlado desde cualquier parte
- Lazy loading: Puede crear la instancia solo cuando se necesita
- Control de recursos: Útil para recursos costosos o limitados
Desventajas
- Testing: Dificulta las pruebas unitarias (hard to mock)
- Acoplamiento: Crea dependencias globales ocultas
- Concurrencia: Requiere consideraciones especiales para thread-safety
- Principio de responsabilidad única: Viola SRP (controla instanciación + lógica de negocio)
Cuándo usar
- Necesitas exactamente una instancia de una clase
- Requieres acceso global a esa instancia
- La instancia debe ser creada de forma lazy
- Controlas recursos compartidos (conexiones, caches)
Cuándo NO usar
- Puedes usar Dependency Injection
- Necesitas múltiples instancias en el futuro
- Dificulta el testing
- Crea acoplamiento innecesario
- El framework ya maneja singletons (Spring Boot)
Alternativas modernas
- Dependency Injection: Spring Boot maneja singletons automáticamente
- Static classes: Para funcionalidades sin estado
- Factory patterns: Para control más flexible de instancias