Pull to refresh

Первое впечатление об MBLTDev 2015

Reading time4 min
Views4.3K
Первое впечатление об МБЛТ Дев 2015… пока еще не забыл все.

Как 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» также были очень содержательными и полезными.

Спасибо организаторам за достойный «контекст» конференции и докладчикам за информативный день!
Tags:
Hubs:
+3
Comments17

Articles