Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Чистая архитектура с VIPER

Чистая архитектура с VIPER

- Что такое "чистая" архитектура приложений. Чем грозит "грязная" архитектура, чем от нее отличается "чистая" архитектура, и какой от нее профит.
- История появления VIPER.
- Идея VIPER. Как изменяется структура приложения при применении этого подхода.
- Опыт использования VIPER в Rambler&Co. Что мы изменили и добавили.
- Работа с VIPER на примере user story из реального приложения.
- Выводы: чем помогает VIPER и когда его использовать не стоит.

Sergey Krapivenskiy

July 16, 2016
Tweet

More Decks by Sergey Krapivenskiy

Other Decks in Technology

Transcript

  1. Кто мы такие вообще • Rambler & Co - группа

    компаний • Рамблер, Афиша, Lenta.ru, Livejournal, Чемпионат и т.д. • Около 25 разработчиков под iOS • Все мобильные проекты стекаются к нам 2
  2. Грязная архитектура • Огромные классы с кучей ответственностей • Сильная

    связанность компонентов • Трудно дебажить • Трудно вносить изменения • Невозможно покрыть тестами • Хочется все сжечь ! 4
  3. Чистая архитектура • Простые компоненты с четкими обязанностями • Слабая

    связанность • Легко покрывается тестами • Легко вносить изменения • Просто понять 5
  4. Идея VIPER • Приложение разбивается на блоки с однотипной структурой

    • Принцип разбиения — по user story • User story описывает поведение приложения 14
  5. User story Пример — лента фото в Instagram Задача —

    отобразить последние фото друзей При необходимости можно перейти на другие истории 15
  6. User story Список лайков к нашим фото — другая история

    Это простые примеры: 1 экран = 1 история 16
  7. User story На одном экране может быть несколько разных историй

    1. Лента фотографий 18 1. Лента фотографий 2. Таб-бар для переключения ленты 3. Панель с информацией о пользователе
  8. User story На одном экране может быть несколько разных историй

    1. Лента фотографий 2. Таб-бар для переключения ленты 19 1. Лента фотографий 2. Таб-бар для переключения ленты 3. Панель с информацией о пользователе
  9. User story На одном экране может быть несколько разных историй

    1. Лента фотографий 2. Таб-бар для переключения ленты 3. Панель с информацией о пользователе 20
  10. Действия модуля • Получает данные • Преобразовывает данные для отображения

    • Реагирует на действия пользователя • Переходит на другие модули при необходимости 21
  11. E PRESENTER VIEW INTERACTOR WIREFRAME E 23 Канонический модуль VIPER

    Отображает на экране полученные данные Информирует модуль о действиях пользователя
  12. E PRESENTER VIEW INTERACTOR WIREFRAME E 24 Канонический модуль VIPER

    Содержит всю логику работы с данными
  13. E PRESENTER VIEW INTERACTOR WIREFRAME E 25 Канонический модуль VIPER

    Подготавливает данные для отображения View Обрабатывает действия пользователя
  14. E PRESENTER VIEW INTERACTOR WIREFRAME E 26 Канонический модуль VIPER

    Отвечает за навигацию модуля Инициализирует модуль и инжектирует зависимости
  15. E PRESENTER VIEW INTERACTOR WIREFRAME E 27 Канонический модуль VIPER

    Простые модельные объекты Не содержат никакой логики
  16. Что мы изменили? • Разделили Wireframe • Добавили слой сервисов

    • Сделали View слоем • Формализовали переходы между модулями • Написали тулзу для кодогенерации 28
  17. Разделили Wireframe • Wireframe не удовлетворяет SRP • Wireframe =

    Router + Assembly • Router отвечает за навигацию • Assembly отвечает за сборку модуля • Dependency Injection с помощью Typhoon Framework • https://github.com/appsquickly/Typhoon 29
  18. Добавили слой сервисов • “Вся бизнес логика” звучит страшно "

    • Сервисы — слой ниже интерактора • 1 сервис = 1 тип сущностей (новости, сообщения, etc) • Сервисы можно переиспользовать в разных модулях • Сервисы зависят от объектов нижнего уровня 30
  19. Слой View • Тяжелое наследие UIViewController • Работа с коллекциями

    не должна быть во View • Layout и анимации можно вынести из View • Эти задачи относятся к отображению данных • Так View превратился в слой 31
  20. Переходы между модулями • То, о чем никто не говорит

    # • У каждого модуля есть <ModuleInput> и <ModuleOutput> • Эти протоколы реализует презентер • Пример: переход из модуля А в модуль B • Роутер модуля А передает данные в презентер модуля B • Презентер модуля B возвращает результат в презентер модуля А 32
  21. Кодогенерация • С VIPER нужно создать кучу классов • Каркас

    всех модулей однотипен • Руками создавать долго и сложно • Программисту лень писать руками? Нужен скрипт • Generamba! • https://github.com/rambler-ios/Generamba 33
  22. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  23. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  24. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  25. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  26. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  27. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  28. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  29. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  30. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  31. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  32. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  33. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  34. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  35. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  36. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  37. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  38. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  39. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  40. VIEW Рестораны в категории INTERACTOR PRESENTER ROUTER SERVICE VIEW Экран

    ресторана INTERACTOR PRESENTER ROUTER SERVICE categoryId restaurants (Core Data) restaurantId restaurant (Core Data) restaurant (PONSO) restaurants (PONSO) 41
  41. Чистая архитектура • Простые компоненты с четкими обязанностями • Слабая

    связанность • Легко покрывается тестами • Легко подвергается изменениям • Просто понять 47
  42. Rambler $ VIPER • Рамблер.Конференции — open-source приложение • Generamba

    — кодогенератор • VIPER McFlurry — набор полезных утилит • The Book Of VIPER — все, что мы знаем о VIPER • И еще некоторые плюшки • https://github.com/rambler-ios 48