Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про IOS: architecture, boundary

Как протоколы помогают в построении архитектуры приложения?

Вопрос проверяет умение применять протоколы для разделения слоев, внедрения зависимостей и повышения тестируемости.

Короткий ответ

Протоколы позволяют описать границы между модулями через контракты. Благодаря этому компоненты зависят не от конкретных классов, а от интерфейсов. Это облегчает замену реализаций, мокирование в тестах и развитие проекта. Протоколы помогают уменьшить связность и избежать «комбайнов» в контроллерах. В архитектурах вроде MVVM, VIPER и Coordinator протоколы — базовый строительный материал.

Длинный ответ

В архитектуре цель обычно одна: сделать код предсказуемым, расширяемым и тестируемым. Протоколы помогают этого достичь, потому что они позволяют явно задать контракты между частями приложения.

Где именно протоколы дают пользу

Перед разбором важно понимать: протоколы не «улучшают архитектуру сами по себе», они улучшают ее, когда применяются на границах ответственности.

1. Разделение слоев через контракты

Например, экран не должен знать, как именно устроен сетевой слой. Он должен знать только «дай мне данные».

Пример контракта репозитория:

protocol UserRepository {
    func loadUser(id: String) async throws -> User
}

ViewModel зависит от UserRepository, а не от конкретного NetworkUserRepository.

2. Dependency Inversion на практике

Компонент верхнего уровня (UI) не зависит от деталей (конкретных сервисов), он зависит от абстракции (протокола).

Что это дает:

  1. Можно заменить реализацию без переписывания UI.

  2. Можно внедрять разные реализации для dev/prod.

  3. Можно изолировать модуль.

3. Улучшение тестирования

С протоколом легко заменить зависимость на мок/спай и проверить поведение.

Пример мока:

final class UserRepositoryMock: UserRepository {
    var result: Result<User, Error> = .failure(NSError())
    func loadUser(id: String) async throws -> User {
        try result.get()
    }
}

Тест проверяет ViewModel, не трогая сеть.

4. Четкие границы модулей

В крупных проектах протоколы помогают ограничить публичную поверхность модуля.

Практика:

  1. В модуле экспортируются только протоколы.

  2. Конкретные классы остаются internal.

  3. Это снижает связанность между фичами.

5. Снижение “Massive View Controller”

Одна из причин разрастания контроллера — он начинает «уметь все»: сеть, парсинг, хранение, навигацию. Протоколы помогают вынести это в отдельные сервисы с понятными контрактами.

Типовой пример архитектурного разреза

Перед примером важно: цель — сделать зависимости направленными и контролируемыми.

  1. UI слой:

    • ViewController / SwiftUI View

  2. Presentation слой:

    • ViewModel / Presenter

  3. Domain/Service слой:

    • UseCase / Interactor / Service

  4. Data слой:

    • Repository / Storage / API

Между слоями:

  • протоколы как границы;

  • реализации “подключаются” через внедрение зависимостей.

Практический вывод

Протоколы особенно полезны на границах слоев: UI ↔ бизнес-логика ↔ данные. Они уменьшают связность, упрощают тестирование и позволяют развивать проект без массовых переписываний.

  • Аватар

    iOS Guru

    Roman Isakov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    5

  • Сложность:

    7

Навыки

  • IOS

    IOS

Ключевые слова

#architecture

#boundary

Подпишись на iOS Developer в телеграм

  • Аватар

    iOS Guru

    Roman Isakov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.