El patrón singleton (unico) es una técnica popular para crear un objeto que existe como una única instancia en la aplicación. En Swift, la implementación del patrón se ha simplificado gracias al soporte para propiedades estáticas y la seguridad de hilos.
Historia del tema:
En Objective-C, la implementación del Singleton requería un código largo y no trivial relacionado con la seguridad de hilos. En Swift, este problema se resuelve gracias a la inicialización perezosa de las propiedades estáticas.
Problema:
El Singleton se usa a menudo para el acceso centralizado al estado de la aplicación (por ejemplo, Sesiones, configuraciones, servicios), pero un uso incorrecto lleva a dependencias implícitas y a una disminución de la testabilidad del código.
Solución:
En Swift, el patrón se implementa a través de una constante estática de tipo. Esto garantiza la seguridad de hilos y la unicidad:
Ejemplo de código:
final class Logger { static let shared = Logger() private init() {} func log(_ message: String) { print(message) } } Logger.shared.log("Ejemplo de funcionamiento del Singleton")
Características clave:
¿Se puede (y debe) usar siempre singleton para cualquier servicio de la aplicación?
No. El Singleton está justificado para un estado verdaderamente global (por ejemplo, ApplicationSettings), pero usarlo para los servicios de lógica comercial es incorrecto: surgen acoplamientos estrechos y problemas de unit-testing.
¿Garantiza static let la inicialización segura de hilos del Singleton en Swift?
Sí, desde Swift 1.2 (y debido a la arquitectura de runtime), static let es seguro por naturaleza — se inicializa una sola vez incluso con la competencia de hilos.
¿Puede ser heredable el singleton?
No. Es mejor declarar la clase como final para evitar la herencia; de lo contrario, se podría crear dos instancias de singletons de diferentes clases heredadas, lo que viola la idea misma del patrón.
Un servicio de trabajo con la red implementado a través de un singleton, y los métodos utilizan un estado global. En las pruebas unitarias aparece una dependencia implícita, reutilizar el servicio es imposible.
Ventajas:
Desventajas:
El Singleton se usa solo para una entidad verdaderamente global — por ejemplo, ApplicationConfig. Todos los servicios obtienen dependencias a través de un inyector explícito.
Ventajas:
Desventajas: