Как iOS-разработчик, признаюсь, что начало было немного скучным, но в целом, помимо докладов на выставке (конференции) было достаточно много интересных моментов. Особого внимания заслуживает упоминание прелестных сестричек из releadgion (спасибо за милые фотки!) и всех очаровательных представительниц прекрасной половины человечества, которые добавили в эту техническую ИТ-конференцию щедрую порцию красоты.
А теперь о самих докладах. Опять же как iOS-разработчика меня в первую очередь интересовали доклады о VIPER-е от Егора Толстого из Rambler&Co и «гладкие TableView» от Александра Орлова из Postforpost. Ребята не подвели — было очень круто! Давно уже изучаю VIPER -было несколько вопросов, ответы на которые мне помогли найти спикеры и участники конференции.
Например, меня интересовал вопрос «что делать, если часть кода из одного Interactor-а нужно использовать в другом?». Ответ, очень прост — выделяем специальный слой services (где и будет весь reusable код).
Однако, не могу согласиться с тем, что для сервисов нужно использовать callback-функции, так как у callback-ов есть очень неприятный недостаток: если нужно в callback-е вызвать еще одну функцию с callback-ом, то возникает такая лапша:
[self someFunctionWithCallbackOnSucces:^{
[weakSelf anotherFunctionWithCallbackOnSucess:^{
// some code 1
} andFail:^{
// some code 1
}];
} andFail:^{
[weakSelf andTheOtherFunctionWithCallbackOnSucess:^{
// some code 2
} andFail:^{
// some code 2
}];
}];
Что на мой, субъективный, взгляд очень снижает читабельность кода. Те же Delegate-ы выглядят в этом плане более предпочтительными (хотя Delegate, при связи один ко многим, смотрится не очень).
Поясню. Как сказал, Егор в докладе «Секреты VIPER» — «Роутер должен роутить». Но проблема в том, что, например, в «эталонной» реализации VIPER By Jeff Gilbert and Conrad Stoll (статья на objc.io), упоминается некий wireframe, который:
1. создает все компоненты
2. конфигурирует зависимости (dependecy injection)
3. роутит
Что не очень согласуется с принципом Single Responsibilty. В рамблер, насколько я понял, для этого используется следующая схема:
1. в storyboard-е мы задаем откуда куда переходить
2. в router-е мы перехватываем prepareForSegue и выполняем инициализацию
3. Typhoon делает Dependecy Injection
На мой, чисто субъективный, взгляд — это создает «ощущение правильности», но более «правильным» будет вынесение всех этих задач в явные классы. То есть:
@interface ModuleA_Router () <ModuleA_Router_Protocol>
@property id<ModuleA_DependencyInjector> di;
@property id<ModueA_ViewFactory> viewFactory;
@property id<ModuleA_InteractorFactory> interactorFactory;
@property id<ModuleA_PresenterFactory> presenterFactory;
@end
@implementation ModuleA_Router
- (void)showViewForModuleA {
// create
id view = [self.viewFactory createViewForModuleAWithParams:...];
id presenter = [self.presenterFactory createPresenterForModuleAWithParams:...];
id interactor = [self.interactorFactory createInteractorForModuleAWithParams:...];
// inject dependencies
[self.di configureModuleAWithView:view presenter:presenter interactor:interactor];
[self.navigationController pushViewController:view];
}
@end
При таком подходе уже неважно какой тул используется для DI, а создание объектов полностью перенесено в factory-классы, которые мы собственно и тестим. Это не противоречит утверждению о том, что «каждый из терминов 'View', 'Presenter', 'Interactor' — это не конкретная сущность, а, скорей слой (который, в общем случае, может состоять из более чем одного класса)».
Еще один докладчик, а именно Kule Fuller, прояснил для меня вопрос о том, какими должны быть идеальные роутеры. В своем докладе он рассказывал, что весь transition у них представляет собой state machine. Что стало неким просветлением, для меня.
Действительно, теперь можно код роутера представить более точно: нарисуем для себя логические переходы со скрина на скрин как конечный автомат, например, так:
+--------------------+ +---------------------+ | state: | ----- {correct Login-Password} ----> | state: | | Authentication | | HomePage | | | | | +--------------------+ +---------------------+ | { wrong Login-Password } | | +---------------------+ | state: | | Registration | | | +---------------------+
При этом, естественно, под конечным автоматом, понимать автомат с частичной функцией переходов (и, использование счетчиков в state-ах, для оптимизации). См. также state pattern от gang of four.
Кроме, того Егор и Rambler, представили миру много своих разработок, связанных с VIPER. Огромное спасибо!
Так, еще один доклад, который, на мой взгляд также достоин упоминания — это доклад об оптимизации TableView. К сожалению, сам доклад получился коротким и мы не успели задать вопросы, но в личной беседе мне все таки удалось узнать у Александра Орлова о различиях между Components Kit и AsyncDisplayKit. Также Александр, поведал, что в целях оптимизации, имеет смысл отказаться от autolayout и делать layout самому. Естественно, это нужно делать, думая головой, а не чем придется (никакого хардкода!). Грамотная реализация данного принципа может быть обнаружена в github.com/plasmLC/PPlayer. Также Александр порекомендовал не использовать CollectionView без веской необходимости.
Справедливости ради, считаю нужным сказать, что доклады от Sally Shpeard «Developing forApple TV», Brigit Lyons «Authentic testing for soundcloud», Chris Eidhof «Swift-like APIs» также были очень содержательными и полезными.
Спасибо организаторам за достойный «контекст» конференции и докладчикам за информативный день!
Комментарии (17)
progn
18.11.2015 12:08По поводу autolayouts, есть конкретные примеры вот тут с ними лагает, а вот тут тоже самое, но отказались от автолайаутов считаем фреймы руками и все стало летать? И девайсы, версии ОС где это проявляется.
«Components Kit и Async UI Kit» это про что? имеется ввиду AsyncDisplayKit от Фейсбука или что-то иное?Naftic
18.11.2015 12:57Async UI Kit — имеется ввиду AsyncDisplayKit от фейсбука.
По поводу, autolayouts — споры бесконечны. Но плюсов от них меньше чем минусов, судя по моему опыту.progn
18.11.2015 13:29ну вот и хочется конкретики, а не споров.
Naftic
18.11.2015 13:55Пока не тормозит — используем автолэйаут, когда начинает тормозить — переходим на ручной счет. Если еще нужно ускорить — переносим в бэкраунд поток, где все и рассчитываем.
Пост от Александра Орлова — habrahabr.ru/post/264817. Пока ничего более путного, чем то, что было в докладе — не встречал.
Также см. github.com/plasmLC/PPlayer (по рекомендации Алексндра).progn
18.11.2015 13:58круто, спасибо!
plasm
18.11.2015 16:40Autolayout ужасно тормозная вещь. В докладе есть цифры, можно посмотреть запись на mbltdev.ru
Пример кода что тут давали не очень красивый, но посмотреть на код контроллеров с ручным layout можно, чтобы понять, что все не так плохо.IgorFedorchuk
18.11.2015 18:23Можно лейаут расчитывать один раз для всех ячеек перед reloadData с использованием Autolayout. И все тоже прекрасно летает. А расчет ручного лейаута — сущий ад. И правильно упоминалось в докладе, что тормоза хорошо проявляются при большом количетве ячеек. Если их до сотни, то вряд ли можно ощутить существенную разницу.
plasm
18.11.2015 18:28Зависит еще от огромного количества факторов. Ручной layout — вполне ок штука, и используется во многих крупных проектах(Telegram, VK, Facebook), потому что IB и Autolayout — днище.
IgorFedorchuk
18.11.2015 18:33Ну это на холивар становится похоже. Есть просто огромная куча проектов, где используют IB и Autolayout и все прекрасно работает.
plasm
18.11.2015 18:35Я приводил цифры, согласно которым очевидно, что нормально работать не будет. Если все прекрасно работает на последних устройствах и элементарным интерфейсом при 30-40 фпс — это не нормально.
IgorFedorchuk
18.11.2015 18:40Надо еще привести цифры по времени на поддержку и написания ручного layout. На счет фпс — надо мерять и смотреть. В большинстве случаев неоправданно писать ручной layout. Хотя скайпу с его тормозами он бы явно не помешал.
plasm
18.11.2015 18:44Секундочку, причем тут время разработки? Речь шла об оптимизации работы UITableView. Скорость разработки с ручным layout у меня и у Вас будет разная, тут ничего толком не померять.
Касательно FPS и скорости работы всё уже измерено — посмотрите доклад. (может позже будет нормальная отдельная запись)IgorFedorchuk
18.11.2015 18:46Согласен с тем, что с ручным layout будет работать быстрее. Доклад видел, статью читал. Ремарка была по поводу поддержки кода, стоит ли овчинка выделки?!
bartleby
А видео докладов будет?
krokhmalyuk
Уже: mbltdev.ru.