← Назад к вопросам

Как устроено взаимодействие компонентов внутри модуля в Clean Swift?

2.0 Middle🔥 111 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Взаимодействие компонентов модуля Clean Swift

В Clean Swift (VIP-цикл) модуль строится вокруг трёх ключевых компонентов: ViewController, Interactor и Presenter, которые взаимодействуют через строгие односторонние потоки данных и протоколы. Эта архитектура реализует принцип Single Responsibility, разделяя логику отображения, бизнес-логику и подготовку данных.

Основные компоненты и их взаимодействие

  1. ViewController — отвечает за:

    • Визуальное представление (UI).
    • Обработку действий пользователя (тапы, жесты).
    • Отображение подготовленных данных.
  2. Interactor — содержит:

    • Всю бизнес-логику модуля.
    • Запросы к сервисам (сети, базам данных).
    • Валидацию данных.
  3. Presenter — выполняет:

    • Форматирование данных из Interactor для отображения.
    • Создание ViewModel (простых структур, готовых для UI).

Поток данных (VIP-цикл)

Типичный сценарий начинается с действия пользователя в ViewController:

// 1. ViewController -> Interactor
class MyViewController: UIViewController {
    func didTapRefreshButton() {
        let request = MyModel.Request()
        interactor?.fetchData(request: request)
    }
}

// 2. Interactor обрабатывает запрос
class MyInteractor {
    func fetchData(request: MyModel.Request) {
        // Выполнение бизнес-логики
        let data = fetchFromService()
        let response = MyModel.Response(data: data)
        
        // 3. Interactor -> Presenter
        presenter?.presentData(response: response)
    }
}

// 4. Presenter форматирует данные
class MyPresenter {
    func presentData(response: MyModel.Response) {
        let viewModel = MyModel.ViewModel(
            title: "Данные загружены",
            items: response.data.map { ItemViewModel(title: $0.name) }
        )
        
        // 5. Presenter -> ViewController
        viewController?.displayData(viewModel: viewModel)
    }
}

// 6. ViewController обновляет UI
extension MyViewController: MyDisplayLogic {
    func displayData(viewModel: MyModel.ViewModel) {
        titleLabel.text = viewModel.title
        tableView.reloadData(with: viewModel.items)
    }
}

Ключевые принципы взаимодействия

  • Однонаправленный поток: Данные движутся строго по цепочке ViewController → Interactor → Presenter → ViewController. Обратного вызова нет.
  • Инкапсуляция через протоколы: Каждый компонент знает о другом только через абстракции (протоколы MyBusinessLogic, MyPresentationLogic, MyDisplayLogic).
  • Models для передачи данных: Используются вложенные структуры Request, Response, ViewModel внутри enum MyModel, что обеспечивает типобезопасность.
  • Отсутствие зависимостей от UIKit: Interactor и Presenter не импортируют UIKit, что упрощает тестирование и переиспользование логики.

Вспомогательные компоненты

  • Router — отвечает за навигацию между модулями и инъекцию зависимостей.
  • Configurator — создаёт все компоненты модуля и связывает их между собой.
  • Worker — выносит рутинные операции (сетевые запросы, работа с Core Data) из Interactor для соблюдения SRP.

Преимущества подхода

  • Чёткое разделение ответственности: Изменение UI не затрагивает бизнес-логику.
  • Лёгкость тестирования: Каждый компонент можно тестировать изолированно с моками.
  • Предсказуемость потока данных: Упрощает отладку и понимание кода новыми разработчиками.

Clean Swift устраняет типичные проблемы Massive View Controller, создавая поддерживаемую и тестируемую архитектуру, где каждый компонент выполняет одну чётко определённую роль.