Чем в современных iOS-фреймворках заменяют паттерн Singleton?

«Чем в современных iOS-фреймворках заменяют паттерн Singleton?» — вопрос из категории Паттерны, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В современных iOS-фреймворках Singleton заменяют следующими подходами:

1. Dependency Injection (DI) — явная передача зависимостей через инициализатор или свойство. Это улучшает тестируемость и читаемость кода.

protocol ServiceProtocol {
    func fetchData() -> Data
}

class ViewModel {
    private let service: ServiceProtocol

    init(service: ServiceProtocol) {
        self.service = service
    }

    func load() -> Data {
        return service.fetchData()
    }
}

2. SwiftUI Environment — использование @EnvironmentObject и @Environment для передачи зависимостей по иерархии представлений.

3. Контейнеры зависимостей — библиотеки типа Swinject или Factory для централизованного управления зависимостями.

4. Акторы (Actors) — для потокобезопасного доступа к общим ресурсам вместо глобального состояния.

@MainActor
class GlobalService {
    static let shared = GlobalService()
    private init() {}

    func update() async { /* ... */ }
}

Почему DI предпочтительнее Singleton?

  • Тестируемость: Легко подменить реальную зависимость моком.
  • Гибкость: Зависимости можно менять без изменения класса.
  • Ясность: Все зависимости явно объявлены в интерфейсе класса.