Ответ
Dependency Injection (DI, внедрение зависимостей) — это архитектурный паттерн, при котором зависимости объекта (сервисы, репозитории, конфигурации) не создаются им самим, а предоставляются извне. Это делает код более гибким, тестируемым и поддерживаемым.
Суть: Разделение создания объекта и использования его зависимостей.
Пример без DI и с DI:
// БЕЗ DI: Жесткая зависимость внутри класса
class ProductServiceWithoutDI {
private let networkManager = NetworkManager() // Зависимость создана внутри
func loadProducts() { /* использует networkManager */ }
}
// С DI: Зависимость внедряется извне
protocol NetworkManaging {
func request(url: URL) -> Data
}
class ProductServiceWithDI {
private let networkManager: NetworkManaging
// Внедрение зависимости через инициализатор (Constructor Injection)
init(networkManager: NetworkManaging) {
self.networkManager = networkManager
}
func loadProducts() { /* использует self.networkManager */ }
}
// В продакшене
let realService = ProductServiceWithDI(networkManager: RealNetworkManager())
// В тестах легко подменить реальную реализацию на мок
let mockService = ProductServiceWithDI(networkManager: MockNetworkManager())
Основные преимущества:
- Тестируемость: Легко подменять реальные реализации на моки или стабы для модульного тестирования.
- Слабая связанность: Классы зависят от абстракций (протоколов), а не от конкретных реализаций.
- Повторное использование: Компоненты становятся более независимыми и переиспользуемыми.
- Гибкость конфигурации: Позволяет централизованно управлять зависимостями (например, через DI-контейнер).
Способы внедрения в Swift: внедрение через инициализатор (наиболее предпочтительный), через свойство (Property Injection), через метод (Method Injection).