Вопрос проверяет знание практических приёмов ослабления связности и улучшения тестируемости.
Основной способ — отказаться от прямого использования shared и внедрять зависимость извне. Для этого используют протоколы и Dependency Injection. Singleton можно оставить как реализацию по умолчанию, но не использовать напрямую. Это позволяет подменять реализацию в тестах. В результате код становится гибче и чище.
Исправление проблемы начинается с явного объявления зависимостей.
protocol AnalyticsTracking {
func track(event: String)
}
class AnalyticsManager: AnalyticsTracking {
static let shared = AnalyticsManager()
private init() {}
}
class UserViewModel {
let analytics: AnalyticsTracking
init(analytics: AnalyticsTracking) {
self.analytics = analytics
}
}
явные зависимости
лёгкая подмена в тестах
соблюдение DIP
Singleton можно использовать как деталь реализации, но зависеть от него напрямую — плохая практика. Dependency Injection решает эту проблему.