Назад к вопросам
Middle+
78
questionbank

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

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

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 через протокол или базовый класс.