Ответ
Dependency Injection (DI, Внедрение зависимостей) — это паттерн проектирования, при котором зависимости объекта предоставляются ему извне, а не создаются внутри. Это делает код слабосвязанным, тестируемым и гибким.
Основные виды DI:
-
Внедрение через инициализатор (Constructor/Initializer Injection)
- Зависимости передаются как параметры инициализатора.
- Преимущество: объект становится неизменяемым (immutable) после создания, зависимость обязательна.
class DataService { private let networkClient: NetworkClient init(networkClient: NetworkClient) { self.networkClient = networkClient } func fetchData() { /* использует networkClient */ } }
-
Внедрение через свойство (Property Injection)
- Зависимость устанавливается через публичное свойство после создания объекта.
- Преимущество: гибкость, возможность изменять зависимость.
- Недостаток: объект может временно находиться в невалидном состоянии.
class ViewController { var analyticsService: AnalyticsService? // Опциональная зависимость } // ... позже vc.analyticsService = AnalyticsService()
-
Внедрение через метод (Method Injection)
- Зависимость передается как параметр метода, где она требуется.
- Преимущество: хорош для зависимостей, которые меняются от вызова к вызову.
class DataProcessor { func process(data: Data, using encoder: JSONEncoder) { /* ... */ } }
Почему DI важен?
- Тестируемость: Легко подменить реальную зависимость (сетевой слой, базу данных) на mock или stub.
- Слабая связанность: Классы не зависят от конкретных реализаций, а от протоколов/абстракций.
- Повторное использование: Компоненты становятся более независимыми и переиспользуемыми.
В iOS/Swift DI часто реализуют вручную, с помощью контейнеров (Swinject, Dip) или используют встроенные механизмы SwiftUI (@EnvironmentObject, @Environment).