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

Какие задачи решает Router?

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

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

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

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

Задачи и функции Router в iOS

Router (или маршрутизатор) — это архитектурный компонент, который отвечает за навигацию между модулями (экранами) приложения, инкапсулируя логику переходов и передачи данных. Его основная цель — отделить навигационную логику от бизнес-логики и представления, что соответствует принципам чистой архитектуры (Clean Architecture) и VIPER.

Ключевые задачи Router

1. Управление навигацией между модулями

Router координирует переходы между экранами, используя UINavigationController, UITabBarController, модальные презентации или кастомные анимации. Он абстрагирует непосредственную работу с UIKit, позволяя легко изменять способ навигации.

protocol ProfileRouterProtocol {
    func openSettings()
    func closeModule()
}

class ProfileRouter: ProfileRouterProtocol {
    weak var viewController: UIViewController?
    
    func openSettings() {
        let settingsVC = SettingsModuleBuilder.build()
        viewController?.navigationController?.pushViewController(settingsVC, animated: true)
    }
}

2. Инкапсуляция зависимостей и создание модулей

Router часто участвует в сборке модулей, используя Builder или Factory паттерны. Он знает, как создать следующий экран и передать ему необходимые зависимости.

class ArticleRouter: ArticleRouterProtocol {
    static func createModule(with articleID: String) -> UIViewController {
        let view = ArticleViewController()
        let presenter = ArticlePresenter()
        let router = ArticleRouter()
        
        view.presenter = presenter
        presenter.view = view
        presenter.router = router
        presenter.articleID = articleID
        router.viewController = view
        
        return view
    }
}

3. Передача данных между модулями

Router обеспечивает передачу данных от текущего модуля к следующему, избегая прямых связей между Presenter или ViewController. Данные передаются через инициализатор или свойства.

func openUserProfile(for userID: String) {
    let profileVC = ProfileModuleBuilder.build(with: userID)
    viewController?.present(profileVC, animated: true)
}

4. Обработка глубоких ссылок (Deep Linking)

Router может парсить URL или схемы глубоких ссылок и преобразовывать их в последовательность навигационных действий, например, открытие определенного экрана с параметрами.

5. Упрощение тестирования

Поскольку навигационная логика изолирована в Router, ее легко тестировать без необходимости загружать реальные UIViewController. Можно создавать моки и проверять корректность вызовов переходов.

class MockRouter: ProfileRouterProtocol {
    var openedSettings = false
    
    func openSettings() {
        openedSettings = true // Флаг для проверки в тестах
    }
}

6. Управление жизненным циклом модуля

Router может отвечать за закрытие модуля, возврат на предыдущий экран или очистку ресурсов, связанных с навигацией.

Преимущества использования Router

  • Снижение связанности: ViewController и Presenter не знают о способе навигации.
  • Централизованное управление: Все переходы описаны в одном месте.
  • Гибкость: Легко изменить способ презентации (например, с push на modal).
  • Масштабируемость: Упрощает добавление новой навигационной логики в больших проектах.

Пример в архитектуре VIPER

В VIPER Router — это отдельный слой (Router), который работает в паре с Presenter. Presenter принимает решения о необходимости перехода, а Router их исполняет.

// Presenter
func didTapEditButton() {
    router?.openEditScreen(for: itemID)
}

// Router
func openEditScreen(for itemID: String) {
    let editVC = EditModuleBuilder.build(with: itemID)
    viewController?.navigationController?.pushViewController(editVC, animated: true)
}

Альтернативы и современные подходы

  • Координаторы (Coordinators): Более мощный паттерн, управляющий потоком целой группы экранов.
  • Router в сочетании с Assembly: Внедрение зависимостей через DI-контейнеры (Swinject, Needle).
  • SwiftUI Navigation: В SwiftUI навигация часто управляется через NavigationStack и состояние, но концепция маршрутизации остается актуальной.

Итог: Router решает задачи декомпозиции навигации, передачи данных и управления зависимостями, делая код модульным, тестируемым и поддерживаемым. Это критически важный компонент в современных iOS-архитектурах для приложений средней и высокой сложности.

Какие задачи решает Router? | PrepBro