Какие абстракции можно использовать для связи между модулями или компонентами в iOS?

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

Ответ

Для связи между компонентами в iOS применяют несколько ключевых абстракций:

  1. Протоколы (Protocols)

    • Для чего: Определение четкого контракта (интерфейса) между компонентами.
    • Плюсы: Строгая типизация, легкое тестирование с моками, поддержка принципа инверсии зависимостей.
      protocol DataProvider {
      func loadItems() -> [Item]
      }
      class ViewModel {
      let provider: DataProvider // Зависим от абстракции
      }
  2. Замыкания (Closures) / Колбэки

    • Для чего: Передача единичных действий или результатов асинхронных операций.
    • Плюсы: Простота, лаконичность для простых сценариев.
      func fetchData(completion: @escaping (Result<[String], Error>) -> Void)
  3. Декларативные фреймворки (Combine, SwiftUI)

    • Для чего: Реактивная связь на основе данных и событий.
    • Плюсы: Односторонний поток данных, автоматическое обновление UI.
      class ViewModel {
      @Published var items: [String] = [] // Изменение автоматически уведомляет подписчиков
      }
  4. Шина событий (NotificationCenter)

    • Для чего: Широковещательная связь "многие ко многим" для слабосвязанных событий.
    • Плюсы: Простота, встроена в SDK. Минусы: Отсутствие типизации, сложнее отладки.
      // Отправка
      NotificationCenter.default.post(name: .dataDidUpdate, object: nil)
      // Подписка
      NotificationCenter.default.addObserver(...)

Выбор зависит от задачи:

  • Протоколы — для строгой, тестируемой связи между слоями.
  • Combine/SwiftUI — для современного реактивного UI.
  • Замыкания — для простых асинхронных колбэков.
  • NotificationCenter — для системных или глобальных событий.