Sobes.tech
Middle+

Hoe kan het gebruik van het Singleton-patroon de principes van polymorfisme schenden?

sobes.tech AI

Antwoord van AI

Singleton beperkt het creëren van instanties van een klasse tot één object. Polymorfisme daarentegen, impliceert de mogelijkheid om met objecten van verschillende klassen te werken via een gemeenschappelijke interface of basisklasse.

Overschrijding gebeurt wanneer de clientcode rigide gekoppeld is aan een specifieke Singleton-klasse, in plaats van te werken met een abstractie (protocol of basisklasse). In dat geval is het niet mogelijk om een ander, alternatief object te gebruiken dat dezelfde functionaliteit implementeert, omdat de client precies een Singleton-voorbeeld verwacht.

// Slechte praktijk - de client is direct afhankelijk van ConcreteSingleton
class ConcreteSingleton {
    static let shared = ConcreteSingleton()
    private init() {}

    func performAction() {
        print("Actie uitvoeren vanuit ConcreteSingleton")
    }
}

// Client
func clientFunction() {
    // Strakke koppeling aan ConcreteSingleton
    ConcreteSingleton.shared.performAction()
}

// Goede praktijk - de client hangt af van een protocol
protocol Service {
    func performAction()
}

class RealService: Service {
    func performAction() {
        print("Actie uitvoeren vanuit RealService")
    }
}

class MockService: Service {
    func performAction() {
        print("Actie uitvoeren vanuit MockService")
    }
}

// Singleton voor het leveren van implementaties via een protocol (optioneel, kan DI gebruiken)
class ServiceProvider {
    static let shared = ServiceProvider()
    private init() {}

    private var currentService: Service = RealService()

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

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

// Client
func flexibleClientFunction() {
    // Werken via abstractie (protocol)
    let service = ServiceProvider.shared.getService()
    service.performAction()
}

// Voorbeelden van polymorfisme met flexibele client
// ServiceProvider.shared.setService(MockService())
// flexibleClientFunction() zal MockService gebruiken

Dus, het direct gebruik van de statische eigenschap shared van de Singleton in de clientcode vermindert de flexibiliteit en bemoeilijkt het vervangen van implementaties, wat een kernaspect is van polymorfisme bij het werken met verschillende objecttypes via een gemeenschappelijke interface. De oplossing is om met de Singleton instantie te werken via een protocol of basisklasse.