Sobes.tech
Middle+

Wie kann die Verwendung des Singleton-Musters die Prinzipien der Polymorphie verletzen?

sobes.tech KI

Antwort von AI

Singleton beschränkt die Erstellung von Instanzen einer Klasse auf ein einzelnes Objekt. Polymorphismus hingegen ermöglicht die Arbeit mit Objekten verschiedener Klassen über eine gemeinsame Schnittstelle oder Basisklasse.

Verletzungen treten auf, wenn der Client-Code starr an eine konkrete Singleton-Klasse gebunden ist, anstatt mit einer Abstraktion (Protokoll oder Basisklasse) zu arbeiten. In diesem Fall ist es nicht möglich, ein anderes, alternatives Objekt zu verwenden, das die gleiche Funktionalität implementiert, da der Client genau eine Singleton-Instanz erwartet.

// Schlechte Verwendung - der Client ist direkt von ConcreteSingleton abhängig
class ConcreteSingleton {
    static let shared = ConcreteSingleton()
    private init() {}

    func performAction() {
        print("Aktion von ConcreteSingleton")
    }
}

// Client
func clientFunction() {
    // Starr an ConcreteSingleton gebunden
    ConcreteSingleton.shared.performAction()
}

// Gute Verwendung - der Client hängt von einem Protokoll ab
protocol Service {
    func performAction()
}

class RealService: Service {
    func performAction() {
        print("Aktion von RealService")
    }
}

class MockService: Service {
    func performAction() {
        print("Aktion von MockService")
    }
}

// Singleton zur Bereitstellung der Implementierung über ein Protokoll (optional, kann DI verwenden)
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() {
    // Arbeit über die Abstraktion (Protokoll)
    let service = ServiceProvider.shared.getService()
    service.performAction()
}

// Beispiele für Polymorphismus mit flexiblem Client
// ServiceProvider.shared.setService(MockService())
// flexibleClientFunction() wird MockService verwenden

Daher reduziert die direkte Verwendung der statischen Eigenschaft shared des Singletons im Client-Code die Flexibilität und erschwert den Austausch von Implementierungen, was ein Schlüsselelement des Polymorphismus ist, wenn mit verschiedenen Objekttypen über eine gemeinsame Schnittstelle gearbeitet wird. Die Lösung besteht darin, die Singleton-Instanz über ein Protokoll oder eine Basisklasse zu verwenden.