2016-08-20 02 Антон Ковалев, Антон Кормаков. viper. Чистая...
TRANSCRIPT
VIPERЧистая архитектура для iOS
Знакомство с VIPER
● Доклад и обсуждения на MBLTDev’15
● Конференция Rambler.iOS V
● Различные статьи и видео
2
MVC
3
VIEW
CONTROLLER
MODEL
User action
Update Notify
Update
Cocoa MVC
4
VIEW
UIView
CONTROLLER
UIViewControllerMODEL
Update
Notify
Минусы
● В контроллерах смешивается бизнес-логика и UI
● MVC == Massive View Controllers
● Глобальные стейты и переменные
● Контроллеры тяжело тестировать
Cocoa MVC
5
SOLID
S - Single responsibility principle (Принцип единственной ответственности)
O - Open/closed principle (Принцип открытости/закрытости)
L - Liskov substitution principle (Принцип подстановки Барбары Лисков)
I - Interface segregation principle (Принцип разделения интерфейса)
D - Dependency inversion principle (Принцип инверсии зависимостей)
6
VIPER
7
ROUTER
VIEW PRESENTER
E
E
INTERACTOR
● Четкое распределение ролей внутри модуля
● Легкая расширяемость и поддержка
● Тестируемость
● Избавление от Massive View Controllers
Что обещает VIPER?
8
VIPER от Rambler
9
ASSEMBLY
ROUTER
VIEW PRESENTER INTERACTOR
SERVICE
SERVICE
SERVICE
E
E
VIEW
● Пассивна
● Отвечает только за передачу событий в PRESENTER
10
ASSEMBLY
ROUTER
VIEW PRESENTER INTERACTOR
SERVICE
SERVICE
SERVICE
E
E
INTERACTOR
● Бизнес-логика
11
ASSEMBLY
ROUTER
VIEW PRESENTER INTERACTOR
SERVICE
SERVICE
SERVICE
E
E
PRESENTER
● Сердце модуля
12
ASSEMBLY
ROUTER
VIEW PRESENTER INTERACTOR
SERVICE
SERVICE
SERVICE
E
E
ROUTER
● Переходы
13
ASSEMBLY
ROUTER
VIEW PRESENTER INTERACTOR
SERVICE
SERVICE
SERVICE
E
E
ASSEMBLY
● Сборщик модуля
● Typhoon
14
ASSEMBLY
ROUTER
VIEW PRESENTER INTERACTOR
SERVICE
SERVICE
SERVICE
E
E
SERVICE
● Бизнес-логика
● INTERACTOR превращается в фасад над сервисами
15
ASSEMBLY
ROUTER
VIEW PRESENTER INTERACTOR
SERVICE
SERVICE
SERVICE
E
E
VIPER на практике
16
О приложении
● Новости
● Объявления
● События
● Профили пользователей
и многое другое…
Практически все экраны приложения – таблица
Практически все экраны отображают данные, полученные с сервера
17
Типовой модуль
ASSEMBLY
<ViewOutput> <InteractorInput>
<RouterInput>
<Service>
UIViewController
UIView, UIControl
ФабрикиUI-компонентов
Фабрики view model
Состояние модуля
Фабрики сабмодулей
Обработка событий от View
Обновление View
Взаимодействие с сервисами
<ModuleInput> <ModuleOutput>
Сетевые запросы
Данные сессии
Информация о текущем пользователе
Настройки приложения
VIEW PRESENTER INTERACTOR
ROUTER
<ViewInput> <InteractorOutput> SERVICE
18
Работа типового модуляНачальная загрузка
objectsobjects
Presenter InteractorView
19
viewDidLoad
displayData:
didTriggerReadyEvent
didFetchData:
fetchData
Работа типового модуляПодгрузка данных
objectsobjects
Presenter InteractorView
20
onInfiniteScroll:
appendData:
didTriggerInfiniteScrollEvent:
didFetchNextData:
fetchNextData
Работа типового модуляОбработка внешних событий
objectsobjects
Presenter InteractorView
21
prependData: didReceiveData: didReceivePushNotification:
Сервисы и их зависимости
● Single responsibility
● Взаимодейтвие через протоколы
● Dependency Injection (Typhoon)
22
FeedService
FeedBlocksFactoryRequestCreator
SessionStorage
AppConfiguration
Переходы
objects
Feed Router Transition HandlerFeed Presenter
23
prependData: showJobContentWithObject:
openModule:
configureWithObject:
id
Module Input
objects
Job Presenter (Module Input)
Разбиение на модули
24
Navigation module
Tabbar module
Feed module
Jobs module
Разбиение на модули
25
Carousel module
People module
Взаимодействие с сабмодулями
26
ASSEMBLY
<ViewOutput> <InteractorInput>
<RouterInput>
<ModuleInput> <ModuleOutput>
VIEW PRESENTER INTERACTOR
ROUTER
<ViewInput> <InteractorOutput>
VIEWPRESENTER<ViewOutput>
<ViewInput>
<Input><Output>
Main Module
Submodule
Взаимодействие с сабмодулями
objects
Jobs moduleFeed module
27
Fetch content
Instantiate modules
Prepare sections
Display sections
configureModule
sectionItemWithObject:view model
Insert cells ‘SHOW MORE’ tapIndex path
● Переиспользование сабмодулей
● Общая логика
● Общие элементы
● Однотипное представление
Контент экраны
28
Базовый модуль
29
Base View Base Presenter Base Interactor
Base Router
Service1
Service2
Job View
Job Assembly
Job Presenter Job Interactor
Job Router
Service3
Итоги
30
Первые впечатления
● ААА! Сложна!
● Очень много связей
● Assembly(Typhoon) == Магия
● Это overkill
31
Если разобраться
● Все абсолютно прозрачно
● Все связи логичные
● Assembly(Typhoon) == Фреймворк
32
Merge
● Xcode не умеет безболезненно добавлять файлы в проект
● Огромное число конфликтов
● Merge мог занимать около 40 минут
33
xUnique
● Скрипт на python
● Встраивается в проект как post-build action
● В разы уменьшает количество конфликтов
Минусы
● После работы скрипта теряется текущая навигация проекта
● Если вызвать несколько раз одновременно - поломает проект
34
Кодогенератор
Generamba
● Рутинные тесты создаются сразу
● Легко создавать свои шаблоны
● Гибкость внутри шаблонов
● Отзывчивость разработчиков
35
Адаптация к изменяющимся требованиям
36
Адаптация к изменяющимся требованиям
3737
Адаптация к изменяющимся требованиям
● Новый модуль для свайпа контента
● Подготовка старых контент модулей к отображению в новом
● Всю логику получения и кеширования контента переместили в
новый сервис
38
Тестирование
● Взаимодействие внутри модуля
● Взаимодействие между модулями
● Взаимодействие модулей с сервисами
● Сервисы
39
Итог
● Проект поделен на модули
● Бизнес-логика отделена от UI
● Проект легко покрывается тестами
● Предсказуемость поведения
● VIPER сочетается с scrum
40
Вопросы?
41