Sobes.tech
Middle+

¿Cómo puede el uso del patrón Singleton violar los principios de polimorfismo?

sobes.tech AI

Respuesta de la IA

Singleton limita la creación de instancias de una clase a un solo objeto. Sin embargo, el polimorfismo implica la capacidad de trabajar con objetos de diferentes clases a través de una interfaz común o una clase base.

La violación ocurre cuando el código cliente se vincula rígidamente a una clase concreta Singleton, en lugar de trabajar con una abstracción (protocolo o clase base). En este caso, no es posible sustituir por otro objeto alternativo que implemente la misma funcionalidad, ya que el cliente espera exactamente una instancia de Singleton.

// Uso incorrecto - el cliente depende directamente de ConcreteSingleton
class ConcreteSingleton {
    static let shared = ConcreteSingleton()
    private init() {}

    func performAction() {
        print("Realizando acción desde ConcreteSingleton")
    }
}

// Cliente
func clientFunction() {
    // Dependencia rígida de ConcreteSingleton
    ConcreteSingleton.shared.performAction()
}

// Uso correcto - el cliente depende de un protocolo
protocol Service {
    func performAction()
}

class RealService: Service {
    func performAction() {
        print("Realizando acción desde RealService")
    }
}

class MockService: Service {
    func performAction() {
        print("Realizando acción desde MockService")
    }
}

// Singleton para proporcionar implementación a través de un protocolo (opcional, puede usarse DI)
class ServiceProvider {
    static let shared = ServiceProvider()
    private init() {}

    private var currentService: Service = RealService()

    func setService(_ service: Service) {
        currentService = service
    }

    func getService() -> Service {
        return currentService
    }
}

// Cliente
func flexibleClientFunction() {
    // Trabajando a través de la abstracción (protocolo)
    let service = ServiceProvider.shared.getService()
    service.performAction()
}

// Ejemplos de polimorfismo con cliente flexible
// ServiceProvider.shared.setService(MockService())
// flexibleClientFunction() usará MockService

Por lo tanto, el uso directo de la propiedad estática shared del Singleton en el código cliente reduce la flexibilidad y dificulta la sustitución de implementaciones, lo cual es un aspecto clave del polimorfismo al trabajar con diferentes tipos de objetos a través de una interfaz común. La solución es trabajar con la instancia del Singleton a través de un protocolo o clase base.