Sobes.tech
Back to questions
Middle+
99
questionbank

Как использование паттерна Singleton может нарушать принципы полиморфизма?

Sobes Copilot

Get answers in real time

Answer from AI

sobes.tech AI

Singleton ограничивает создание экземпляров класса одним объектом. Полиморфизм же предполагает возможность работы с объектами различных классов через общий интерфейс или базовый класс.

Нарушение происходит, когда клиентский код жестко привязывается к единственному конкретному классу Singleton, вместо того чтобы работать с абстракцией (протоколом или базовым классом). В этом случае невозможно подставить другой, альтернативный объект, реализующий ту же функциональность, поскольку клиент ожидает именно экземпляр Singleton.

// Плохое использование - клиент прямо зависит от ConcreteSingleton
class ConcreteSingleton {
    static let shared = ConcreteSingleton()
    private init() {}

    func performAction() {
        print("Performing action from ConcreteSingleton")
    }
}

// Клиент
func clientFunction() {
    // Жесткая привязка к ConcreteSingleton
    ConcreteSingleton.shared.performAction()
}

// Хорошее использование - клиент зависит от протокола
protocol Service {
    func performAction()
}

class RealService: Service {
    func performAction() {
        print("Performing action from RealService")
    }
}

class MockService: Service {
    func performAction() {
        print("Performing action from MockService")
    }
}

// Singleton для предоставления реализации через протокол (опционально, можно использовать 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
    }
}

// Клиент
func flexibleClientFunction() {
    // Работа через абстракцию (протокол)
    let service = ServiceProvider.shared.getService()
    service.performAction()
}

// Примеры полиморфизма с гибким клиентом
// ServiceProvider.shared.setService(MockService())
// flexibleClientFunction() будет использовать MockService

Таким образом, прямое использование статического свойства shared Singleton в клиентском коде снижает гибкость и мешает подменять реализации, что является ключевым аспектом полиморфизма при работе с разными типами объектов через общий интерфейс. Решением является работа с экземпляром Singleton через протокол или базовый класс.