SlideShare a Scribd company logo
1 of 56
Download to read offline
Александр Сычев
Разработчик iOS
RAMBLER.iOS V
Как разобрать Massive View Controller
и сделать из него VIPER-модуль
Massive View Controller -> VIPER
Проблемы Massive View Controller
Примеры
Немного статистики
Massive View Controller -> VIPER
Проблемы Massive View Controller
Примеры
Немного статистики
Massive View Controller -> VIPER
Dark Massive View Controller Light VIPER
Massive View Controller -> VIPER
Model View Controller
ModelView
Controller
Mediator
Strategy
User
action
Update
Update
Notify
Massive View Controller -> VIPER
Massive View Controller
Massive View Controller -> VIPER
•Высокая сложность поддержки и развития
•Высокий порог вхождения
•Слабо тестируем
•Невозможно переиспользовать
•Редактор притормаживает на 5 000 строк кода 😃
Недостатки Massive View Controller
Massive View Controller -> VIPER
Massive View Controller -> VIPER
Проблемы Massive View Controller
Примеры
Немного статистики
Massive View Controller -> VIPER
Massive View Controller -> VIPER
Massive View Controller -> VIPER
Переход между экранами
Massive View Controller -> VIPER
View Presenter Interactor Router
Переход между экранами
Massive View Controller -> VIPER
@protocol AGMainMenuControllerViewOutput <NSObject>
- (void)showMenuSectionWithType:(MainMenuSectionType)sectionType
fromViewController:(UIViewController *)viewController;
@end
View Presenter Interactor Router
Massive View Controller -> VIPER
View Presenter Interactor Router
Handle event
@protocol AGMainMenuControllerViewOutput <NSObject>
- (void)showMenuSectionWithType:(MainMenuSectionType)sectionType
fromViewController:(UIViewController *)viewController;
@end
Massive View Controller -> VIPER
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath {
NSInteger index = indexPath.row;
[self.output showMenuSectionWithType:index
fromViewController:self];
}
View Presenter Interactor Router
Handle event
Massive View Controller -> VIPER
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath {
NSInteger index = indexPath.row;
[self.output showMenuSectionWithType:index
fromViewController:self];
}
View Presenter Interactor Router
Handle eventTable delegate
Massive View Controller -> VIPER
@protocol AGMainMenuRouterInput <NSObject>
- (void)showCityFromViewController:(UIViewController *)vcS;
- (void)showPlacesFromViewController:(UIViewController *)vcS;
- (void)showReferenceBookFromViewController:(UIViewController *)vcS;
@end
View Presenter Interactor Router
Handle eventTable delegate
Massive View Controller -> VIPER
@protocol AGMainMenuRouterInput <NSObject>
- (void)showCityFromViewController:(UIViewController *)vcS;
- (void)showPlacesFromViewController:(UIViewController *)vcS;
- (void)showReferenceBookFromViewController:(UIViewController *)vcS;
@end
View Presenter Interactor Router
Handle eventTable delegate Module routing
Massive View Controller -> VIPER
- (void)showMenuSectionWithType:(MainMenuSectionType)sectionType
fromViewController:(UIViewController *)viewController {
switch (sectionType) {
<Call RouterInput methods>
}
}
View Presenter Interactor Router
Handle eventTable delegate Module routing
Massive View Controller -> VIPER
- (void)showMenuSectionWithType:(MainMenuSectionType)sectionType
fromViewController:(UIViewController *)viewController {
switch (sectionType) {
<Call RouterInput methods>
}
}
View Presenter Interactor Router
Handle eventTable delegate Module routing
Call Router
Massive View Controller -> VIPER
- (void)showCityFromViewController:(UIViewController *)vcS {
UIStoryboard *sb = <Load storyboard>;
UIViewController *vcD = <Instantiate ViewController>;
[vcS.navigationController pushViewController:vcD
animated:YES];
}
View Presenter Interactor Router
Handle eventTable delegate Module routing
Call Router
Massive View Controller -> VIPER
Переход между экранами
Massive View Controller VIPER
Massive View Controller -> VIPER
Чтение данных
Massive View Controller -> VIPER
Чтение данных
View Presenter Interactor Router
Massive View Controller -> VIPER
@protocol AGMainMenuControllerViewOutput <NSObject>
- (void)obtainQuarters;
@end
View Presenter Interactor Router
Massive View Controller -> VIPER
View Presenter Interactor Router
@protocol AGMainMenuControllerViewOutput <NSObject>
- (void)obtainQuarters;
@end
Handle event
Massive View Controller -> VIPER
- (void)viewDidLoad {
[super viewDidLoad];
[self.output obtainQuarters];
}
View Presenter Interactor Router
Handle event
Massive View Controller -> VIPER
- (void)viewDidLoad {
[super viewDidLoad];
[self.output obtainQuarters];
}
View Presenter Interactor Router
Handle eventAsk for data
Massive View Controller -> VIPER
- (void)obtainQuarters {
[self.view showSpinners];
[self.interactor loadQuarters];
}
View Presenter Interactor Router
Handle eventAsk for data
Massive View Controller -> VIPER
- (void)obtainQuarters {
[self.view showSpinners];
[self.interactor loadQuarters];
}
View Presenter Interactor Router
Handle eventAsk for data
Call Interactor
Massive View Controller -> VIPER
- (void)loadQuarters {
<Prepare loading request>
NSArray *quarters = [AGQuarter MR_findAllSortedBy:sortTerm
inContext:context];
NSArray *ponsoQuarters = [self createPlainObjectsFrom:quarters];
[self.output loadedQuarters:ponsoQuarters];
}
View Presenter Interactor Router
Handle eventAsk for data
Call Interactor
Massive View Controller -> VIPER
- (void)loadQuarters {
<Prepare loading request>
NSArray *quarters = [AGQuarter MR_findAllSortedBy:sortTerm
inContext:context];
NSArray *ponsoQuarters = [self createPlainObjectsFrom:quarters];
[self.output loadedQuarters:ponsoQuarters];
}
View Presenter Interactor Router
Handle eventAsk for data
Call Interactor
Load data
Massive View Controller -> VIPER
- (void)loadedQuarters:(NSArray *)quarters {
[self.view hideSpinners];
[self.view handleObtainedQuarters:quarters];
}
View Presenter Interactor Router
Handle eventAsk for data
Call Interactor
Load data
Massive View Controller -> VIPER
- (void)loadedQuarters:(NSArray *)quarters {
[self.view hideSpinners];
[self.view handleObtainedQuarters:quarters];
}
View Presenter Interactor Router
Handle eventAsk for data
Call Interactor
Load data
Prepare data
Massive View Controller -> VIPER
View Presenter Interactor Router
Handle eventAsk for data
Call Interactor
Load data
Prepare data
- (void)handleObtainedQuarters:(NSArray *)quarters {
<Display quarters>
}
Massive View Controller -> VIPER
- (void)handleObtainedQuarters:(NSArray *)quarters {
<Display quarters>
}
View Presenter Interactor Router
Handle eventAsk for data
Call Interactor
Load data
Prepare data
Display data
Massive View Controller -> VIPER
Чтение данных
Massive View Controller VIPER
Massive View Controller -> VIPER
Конфигурация объектов
Massive View Controller -> VIPER
AssemblyVIPER-модуль
Конфигурация объектов
Massive View Controller -> VIPER
@interface AGMainMenuInteractor : NSObject <AGMainMenuInteractorInput>
@property (weak) id<AGMainMenuInteractorOutput> output;
@property (strong) id<AGImageLocalCacheManager> imageLocalCacheManager;
@end
AssemblyVIPER-модуль
Massive View Controller -> VIPER
@interface AGMainMenuInteractor : NSObject <AGMainMenuInteractorInput>
@property (weak) id<AGMainMenuInteractorOutput> output;
@property (strong) id<AGImageLocalCacheManager> imageLocalCacheManager;
@end
AssemblyVIPER-модуль
Load image
Massive View Controller -> VIPER
- (AGMainMenuInteractor *)interactorMainMenu {
return [TyphoonDefinition
withClass:[AGMainMenuInteractor class]
configuration:^(TyphoonDefinition *definition) {
[definition injectProperty:@selector(imageLocalCacheManager)
with:[self.coreHelpersAssembly imageLocalCacheManager]];
}];
}
AssemblyVIPER-модуль
Load image
Massive View Controller -> VIPER
- (AGMainMenuInteractor *)interactorMainMenu {
return [TyphoonDefinition
withClass:[AGMainMenuInteractor class]
configuration:^(TyphoonDefinition *definition) {
[definition injectProperty:@selector(imageLocalCacheManager)
with:[self.coreHelpersAssembly imageLocalCacheManager]];
}];
}
AssemblyVIPER-модуль
Load image Configure Module
Massive View Controller -> VIPER
- (id<AGImageLocalCacheManager>)imageLocalCacheManager {
return [TyphoonDefinition
withClass:[AGImageLocalCacheManagerImplementation class]
configuration:^(TyphoonDefinition *definition) {
[definition useInitializer:@selector(managerWithFileManager:)
parameters:^(TyphoonMethod *initializer) {
[initializer injectParameterWith:[self fileManager]];
}];
}];
}
CoreHelpersAssembly
Massive View Controller -> VIPER
AssemblyVIPER-модуль
Load image
Конфигурация объектов
- (void)loadBackgroundImage {
UIImage *guideBackgroundImage = [self.imageLocalCacheManager
loadImageWithImageId:guide.backgroundImage.photoId];
[self.output loadedBackgroundImage:guideBackgroundImage];
}
Configure Module
Massive View Controller -> VIPER
AssemblyVIPER-модуль
Use Core HelpersLoad image
Конфигурация объектов
- (void)loadBackgroundImage {
UIImage *guideBackgroundImage = [self.imageLocalCacheManager
loadImageWithImageId:guide.backgroundImage.photoId];
[self.output loadedBackgroundImage:guideBackgroundImage];
}
Configure Module
- (void)loadBackgroundImage {
UIImage *guideBackgroundImage = [self.imageLocalCacheManager
loadImageWithImageId:guide.backgroundImage.photoId];
[self.output loadedBackgroundImage:guideBackgroundImage];
}
Massive View Controller -> VIPER
Конфигурация объектов
Massive View Controller VIPER
Massive View Controller -> VIPER
View
Interactor
Presenter
Router
Assembly
Massive View Controller -> VIPER
View
Interactor
Presenter
Router
Assembly
Massive View Controller -> VIPER
Трудозатраты
24 человеко-часа
Massive View Controller -> VIPER
Проблемы Massive View Controller
Примеры
Немного статистики
Massive View Controller -> VIPER
Статистика
MVC VIPER
R1 ~9,3K / 0,175K ~18K / 0,58K
R2 ~7,6K / 0,54K ~1,1K / 0,55K
R3 ~3,8K / 0,38K ~8,4K / 0,53K
Massive View Controller -> VIPER
> 1,5 раза
Massive View Controller -> VIPER
Выводы
VIPER MVC
Massive View Controller -> VIPER
Спасибо за
внимание!

More Related Content

What's hot

MBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&CoMBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&Coe-Legion
 
MVVM Light Toolkit Works Great, Less Complicated
MVVM Light ToolkitWorks Great, Less ComplicatedMVVM Light ToolkitWorks Great, Less Complicated
MVVM Light Toolkit Works Great, Less Complicatedmdc11
 
Backbone.js
Backbone.jsBackbone.js
Backbone.jsVO Tho
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widgetTudor Barbu
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO DevsWO Community
 
D2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRollerD2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRollerWO Community
 
Sitecore MVC (London User Group, April 29th 2014)
Sitecore MVC (London User Group, April 29th 2014)Sitecore MVC (London User Group, April 29th 2014)
Sitecore MVC (London User Group, April 29th 2014)Ruud van Falier
 
AngularJS Deep Dives (NYC GDG Apr 2013)
AngularJS Deep Dives (NYC GDG Apr 2013)AngularJS Deep Dives (NYC GDG Apr 2013)
AngularJS Deep Dives (NYC GDG Apr 2013)Nitya Narasimhan
 
Infrastructure as Code 삽질기
Infrastructure as Code 삽질기Infrastructure as Code 삽질기
Infrastructure as Code 삽질기Changwan Jun
 
Model-View-Controller: Tips&Tricks
Model-View-Controller: Tips&TricksModel-View-Controller: Tips&Tricks
Model-View-Controller: Tips&TricksCiklum Ukraine
 
Using ReactJS in AngularJS
Using ReactJS in AngularJSUsing ReactJS in AngularJS
Using ReactJS in AngularJSBoris Dinkevich
 
.NET Conf 2018: Build Great Libraries using .NET Standard
.NET Conf 2018: Build Great Libraries using .NET Standard.NET Conf 2018: Build Great Libraries using .NET Standard
.NET Conf 2018: Build Great Libraries using .NET StandardImmo Landwerth
 
Bundle deployment at state machine level - Ales Justin, JBoss
Bundle deployment at state machine level - Ales Justin, JBossBundle deployment at state machine level - Ales Justin, JBoss
Bundle deployment at state machine level - Ales Justin, JBossmfrancis
 
Nuxt.JS Introdruction
Nuxt.JS IntrodructionNuxt.JS Introdruction
Nuxt.JS IntrodructionDavid Ličen
 
Drupal point of vue
Drupal point of vueDrupal point of vue
Drupal point of vueDavid Ličen
 

What's hot (20)

MBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&CoMBLTDev15: Egor Tolstoy, Rambler&Co
MBLTDev15: Egor Tolstoy, Rambler&Co
 
Viper
ViperViper
Viper
 
MVVM Light Toolkit Works Great, Less Complicated
MVVM Light ToolkitWorks Great, Less ComplicatedMVVM Light ToolkitWorks Great, Less Complicated
MVVM Light Toolkit Works Great, Less Complicated
 
Conductor vs Fragments
Conductor vs FragmentsConductor vs Fragments
Conductor vs Fragments
 
Backbone.js
Backbone.jsBackbone.js
Backbone.js
 
Introduction to Angular JS
Introduction to Angular JSIntroduction to Angular JS
Introduction to Angular JS
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
 
D2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRollerD2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRoller
 
Sitecore MVC (London User Group, April 29th 2014)
Sitecore MVC (London User Group, April 29th 2014)Sitecore MVC (London User Group, April 29th 2014)
Sitecore MVC (London User Group, April 29th 2014)
 
AngularJS Deep Dives (NYC GDG Apr 2013)
AngularJS Deep Dives (NYC GDG Apr 2013)AngularJS Deep Dives (NYC GDG Apr 2013)
AngularJS Deep Dives (NYC GDG Apr 2013)
 
Spring 4 Web App
Spring 4 Web AppSpring 4 Web App
Spring 4 Web App
 
Infrastructure as Code 삽질기
Infrastructure as Code 삽질기Infrastructure as Code 삽질기
Infrastructure as Code 삽질기
 
Practical ERSync
Practical ERSyncPractical ERSync
Practical ERSync
 
Model-View-Controller: Tips&Tricks
Model-View-Controller: Tips&TricksModel-View-Controller: Tips&Tricks
Model-View-Controller: Tips&Tricks
 
Using ReactJS in AngularJS
Using ReactJS in AngularJSUsing ReactJS in AngularJS
Using ReactJS in AngularJS
 
.NET Conf 2018: Build Great Libraries using .NET Standard
.NET Conf 2018: Build Great Libraries using .NET Standard.NET Conf 2018: Build Great Libraries using .NET Standard
.NET Conf 2018: Build Great Libraries using .NET Standard
 
Bundle deployment at state machine level - Ales Justin, JBoss
Bundle deployment at state machine level - Ales Justin, JBossBundle deployment at state machine level - Ales Justin, JBoss
Bundle deployment at state machine level - Ales Justin, JBoss
 
Nuxt.JS Introdruction
Nuxt.JS IntrodructionNuxt.JS Introdruction
Nuxt.JS Introdruction
 
Drupal point of vue
Drupal point of vueDrupal point of vue
Drupal point of vue
 

Viewers also liked

Rambler.iOS #5: Подмодули в VIPER
Rambler.iOS #5: Подмодули в VIPERRambler.iOS #5: Подмодули в VIPER
Rambler.iOS #5: Подмодули в VIPERRAMBLER&Co
 
Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101RAMBLER&Co
 
Good bye Massive View Controller!
Good bye Massive View Controller!Good bye Massive View Controller!
Good bye Massive View Controller!Supercharge
 
Rambler.iOS #5: Переходы и передача данных между VIPER модулями
Rambler.iOS #5: Переходы и передача данных между VIPER модулямиRambler.iOS #5: Переходы и передача данных между VIPER модулями
Rambler.iOS #5: Переходы и передача данных между VIPER модулямиRAMBLER&Co
 
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложении
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложенииRambler.iOS #7: Прием платежей по банковским картам в iOS приложении
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложенииRAMBLER&Co
 
RDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRAMBLER&Co
 
Rambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRAMBLER&Co
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: PromisesRAMBLER&Co
 
RDSDataSource: OCLint
RDSDataSource: OCLintRDSDataSource: OCLint
RDSDataSource: OCLintRAMBLER&Co
 
RDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDKRDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDKRAMBLER&Co
 
Rambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxprojRambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxprojRAMBLER&Co
 
RDSDataSource: YapDatabase
RDSDataSource: YapDatabaseRDSDataSource: YapDatabase
RDSDataSource: YapDatabaseRAMBLER&Co
 
RDSDataSource: App Thinning
RDSDataSource: App ThinningRDSDataSource: App Thinning
RDSDataSource: App ThinningRAMBLER&Co
 
Rambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #7: Построение сложного табличного интерфейсаRambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #7: Построение сложного табличного интерфейсаRAMBLER&Co
 
Rambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы
Rambler.iOS #4: Создание модульных приложений на примере Рамблер.КассыRambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы
Rambler.iOS #4: Создание модульных приложений на примере Рамблер.КассыRAMBLER&Co
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRAMBLER&Co
 
RDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperiencedRDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperiencedRAMBLER&Co
 
Rambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и SwiftRambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и SwiftRAMBLER&Co
 

Viewers also liked (18)

Rambler.iOS #5: Подмодули в VIPER
Rambler.iOS #5: Подмодули в VIPERRambler.iOS #5: Подмодули в VIPER
Rambler.iOS #5: Подмодули в VIPER
 
Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101
 
Good bye Massive View Controller!
Good bye Massive View Controller!Good bye Massive View Controller!
Good bye Massive View Controller!
 
Rambler.iOS #5: Переходы и передача данных между VIPER модулями
Rambler.iOS #5: Переходы и передача данных между VIPER модулямиRambler.iOS #5: Переходы и передача данных между VIPER модулями
Rambler.iOS #5: Переходы и передача данных между VIPER модулями
 
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложении
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложенииRambler.iOS #7: Прием платежей по банковским картам в iOS приложении
Rambler.iOS #7: Прием платежей по банковским картам в iOS приложении
 
RDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по DipRDSDataSource: Мастер-класс по Dip
RDSDataSource: Мастер-класс по Dip
 
Rambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеров
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: Promises
 
RDSDataSource: OCLint
RDSDataSource: OCLintRDSDataSource: OCLint
RDSDataSource: OCLint
 
RDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDKRDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDK
 
Rambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxprojRambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxproj
 
RDSDataSource: YapDatabase
RDSDataSource: YapDatabaseRDSDataSource: YapDatabase
RDSDataSource: YapDatabase
 
RDSDataSource: App Thinning
RDSDataSource: App ThinningRDSDataSource: App Thinning
RDSDataSource: App Thinning
 
Rambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #7: Построение сложного табличного интерфейсаRambler.iOS #7: Построение сложного табличного интерфейса
Rambler.iOS #7: Построение сложного табличного интерфейса
 
Rambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы
Rambler.iOS #4: Создание модульных приложений на примере Рамблер.КассыRambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы
Rambler.iOS #4: Создание модульных приложений на примере Рамблер.Кассы
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на Swift
 
RDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperiencedRDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperienced
 
Rambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и SwiftRambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и Swift
 

Similar to Rambler.iOS #5: Разбираем Massive View Controller

Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Patterngoodfriday
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM patternNAVER Engineering
 
Sexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroidsSexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroidsDmytro Zaitsev
 
SE2016 Android Dmytro Zaitsev "Viper make your MVP cleaner"
SE2016 Android Dmytro Zaitsev "Viper  make your MVP cleaner"SE2016 Android Dmytro Zaitsev "Viper  make your MVP cleaner"
SE2016 Android Dmytro Zaitsev "Viper make your MVP cleaner"Inhacking
 
What's new in Android P @ I/O Extended Bangkok 2018
What's new in Android P @ I/O Extended Bangkok 2018What's new in Android P @ I/O Extended Bangkok 2018
What's new in Android P @ I/O Extended Bangkok 2018Somkiat Khitwongwattana
 
Asp.Net MVC Framework Design Pattern
Asp.Net MVC Framework Design PatternAsp.Net MVC Framework Design Pattern
Asp.Net MVC Framework Design Patternmaddinapudi
 
Behind the Code 'September 2022 // by Exness
Behind the Code 'September 2022 // by ExnessBehind the Code 'September 2022 // by Exness
Behind the Code 'September 2022 // by ExnessMaxim Gaponov
 
점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정Arawn Park
 
OpenNebula Conf 2014 | Lightning talk: Proactive Autonomic Management Feature...
OpenNebula Conf 2014 | Lightning talk: Proactive Autonomic Management Feature...OpenNebula Conf 2014 | Lightning talk: Proactive Autonomic Management Feature...
OpenNebula Conf 2014 | Lightning talk: Proactive Autonomic Management Feature...NETWAYS
 
OpenNebulaConf 2014 - Lightning talk: Proactive Autonomic Management Features...
OpenNebulaConf 2014 - Lightning talk: Proactive Autonomic Management Features...OpenNebulaConf 2014 - Lightning talk: Proactive Autonomic Management Features...
OpenNebulaConf 2014 - Lightning talk: Proactive Autonomic Management Features...OpenNebula Project
 
Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSVisual Engineering
 
ASP.NET MVC Internals
ASP.NET MVC InternalsASP.NET MVC Internals
ASP.NET MVC InternalsVitaly Baum
 
Android securitybyexample
Android securitybyexampleAndroid securitybyexample
Android securitybyexamplePragati Rai
 
ASP.NET Internals
ASP.NET InternalsASP.NET Internals
ASP.NET InternalsGoSharp
 
SFNode 01-2018 - Aquarium control
SFNode 01-2018 - Aquarium controlSFNode 01-2018 - Aquarium control
SFNode 01-2018 - Aquarium controlBryan Hughes
 
The use case of a scalable architecture
The use case of a scalable architectureThe use case of a scalable architecture
The use case of a scalable architectureToru Wonyoung Choi
 
vVMworld 2013: Deploying, Troubleshooting, and Monitoring VMware NSX Distribu...
vVMworld 2013: Deploying, Troubleshooting, and Monitoring VMware NSX Distribu...vVMworld 2013: Deploying, Troubleshooting, and Monitoring VMware NSX Distribu...
vVMworld 2013: Deploying, Troubleshooting, and Monitoring VMware NSX Distribu...VMworld
 

Similar to Rambler.iOS #5: Разбираем Massive View Controller (20)

Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
 
Sexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroidsSexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroids
 
SE2016 Android Dmytro Zaitsev "Viper make your MVP cleaner"
SE2016 Android Dmytro Zaitsev "Viper  make your MVP cleaner"SE2016 Android Dmytro Zaitsev "Viper  make your MVP cleaner"
SE2016 Android Dmytro Zaitsev "Viper make your MVP cleaner"
 
Dmytro Zaitsev Viper: make your mvp cleaner
Dmytro Zaitsev Viper: make your mvp cleanerDmytro Zaitsev Viper: make your mvp cleaner
Dmytro Zaitsev Viper: make your mvp cleaner
 
What's new in Android P @ I/O Extended Bangkok 2018
What's new in Android P @ I/O Extended Bangkok 2018What's new in Android P @ I/O Extended Bangkok 2018
What's new in Android P @ I/O Extended Bangkok 2018
 
Asp.Net MVC Framework Design Pattern
Asp.Net MVC Framework Design PatternAsp.Net MVC Framework Design Pattern
Asp.Net MVC Framework Design Pattern
 
Behind the Code 'September 2022 // by Exness
Behind the Code 'September 2022 // by ExnessBehind the Code 'September 2022 // by Exness
Behind the Code 'September 2022 // by Exness
 
점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정
 
Mvc - Titanium
Mvc - TitaniumMvc - Titanium
Mvc - Titanium
 
OpenNebula Conf 2014 | Lightning talk: Proactive Autonomic Management Feature...
OpenNebula Conf 2014 | Lightning talk: Proactive Autonomic Management Feature...OpenNebula Conf 2014 | Lightning talk: Proactive Autonomic Management Feature...
OpenNebula Conf 2014 | Lightning talk: Proactive Autonomic Management Feature...
 
OpenNebulaConf 2014 - Lightning talk: Proactive Autonomic Management Features...
OpenNebulaConf 2014 - Lightning talk: Proactive Autonomic Management Features...OpenNebulaConf 2014 - Lightning talk: Proactive Autonomic Management Features...
OpenNebulaConf 2014 - Lightning talk: Proactive Autonomic Management Features...
 
easemesh-architecture.pptx
easemesh-architecture.pptxeasemesh-architecture.pptx
easemesh-architecture.pptx
 
Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
 
ASP.NET MVC Internals
ASP.NET MVC InternalsASP.NET MVC Internals
ASP.NET MVC Internals
 
Android securitybyexample
Android securitybyexampleAndroid securitybyexample
Android securitybyexample
 
ASP.NET Internals
ASP.NET InternalsASP.NET Internals
ASP.NET Internals
 
SFNode 01-2018 - Aquarium control
SFNode 01-2018 - Aquarium controlSFNode 01-2018 - Aquarium control
SFNode 01-2018 - Aquarium control
 
The use case of a scalable architecture
The use case of a scalable architectureThe use case of a scalable architecture
The use case of a scalable architecture
 
vVMworld 2013: Deploying, Troubleshooting, and Monitoring VMware NSX Distribu...
vVMworld 2013: Deploying, Troubleshooting, and Monitoring VMware NSX Distribu...vVMworld 2013: Deploying, Troubleshooting, and Monitoring VMware NSX Distribu...
vVMworld 2013: Deploying, Troubleshooting, and Monitoring VMware NSX Distribu...
 

More from RAMBLER&Co

RDSDataSource: Основы LLVM
RDSDataSource: Основы LLVMRDSDataSource: Основы LLVM
RDSDataSource: Основы LLVMRAMBLER&Co
 
Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Анализируй это!Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Анализируй это!RAMBLER&Co
 
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?RAMBLER&Co
 
Rambler.iOS #9: Life with out of memory
Rambler.iOS #9: Life with out of memoryRambler.iOS #9: Life with out of memory
Rambler.iOS #9: Life with out of memoryRAMBLER&Co
 
RDSDataSource: Построение UML диаграмм
RDSDataSource: Построение UML диаграммRDSDataSource: Построение UML диаграмм
RDSDataSource: Построение UML диаграммRAMBLER&Co
 
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRAMBLER&Co
 
Rambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Сервис-ориентированная архитектураRambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Сервис-ориентированная архитектураRAMBLER&Co
 
Rambler.iOS #8: Make your app extensible with JavaScriptCore
Rambler.iOS #8: Make your app extensible with JavaScriptCoreRambler.iOS #8: Make your app extensible with JavaScriptCore
Rambler.iOS #8: Make your app extensible with JavaScriptCoreRAMBLER&Co
 
RDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOSRDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOSRAMBLER&Co
 
RDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwiftRDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwiftRAMBLER&Co
 
Rambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуйRambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуйRAMBLER&Co
 
Rambler.iOS #6: Pagination Demystified
Rambler.iOS #6: Pagination DemystifiedRambler.iOS #6: Pagination Demystified
Rambler.iOS #6: Pagination DemystifiedRAMBLER&Co
 
Rambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPERRambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPERRAMBLER&Co
 
Rambler.iOS #5: VIPER a la Rambler
Rambler.iOS #5: VIPER a la RamblerRambler.iOS #5: VIPER a la Rambler
Rambler.iOS #5: VIPER a la RamblerRAMBLER&Co
 

More from RAMBLER&Co (14)

RDSDataSource: Основы LLVM
RDSDataSource: Основы LLVMRDSDataSource: Основы LLVM
RDSDataSource: Основы LLVM
 
Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Анализируй это!Rambler.iOS #9: Анализируй это!
Rambler.iOS #9: Анализируй это!
 
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
Rambler.iOS #9: Нужны ли бэкенд-разработчики, когда есть Swift?
 
Rambler.iOS #9: Life with out of memory
Rambler.iOS #9: Life with out of memoryRambler.iOS #9: Life with out of memory
Rambler.iOS #9: Life with out of memory
 
RDSDataSource: Построение UML диаграмм
RDSDataSource: Построение UML диаграммRDSDataSource: Построение UML диаграмм
RDSDataSource: Построение UML диаграмм
 
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тесты
 
Rambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Сервис-ориентированная архитектураRambler.iOS #8: Сервис-ориентированная архитектура
Rambler.iOS #8: Сервис-ориентированная архитектура
 
Rambler.iOS #8: Make your app extensible with JavaScriptCore
Rambler.iOS #8: Make your app extensible with JavaScriptCoreRambler.iOS #8: Make your app extensible with JavaScriptCore
Rambler.iOS #8: Make your app extensible with JavaScriptCore
 
RDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOSRDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOS
 
RDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwiftRDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwift
 
Rambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуйRambler.iOS #6: App delegate - разделяй и властвуй
Rambler.iOS #6: App delegate - разделяй и властвуй
 
Rambler.iOS #6: Pagination Demystified
Rambler.iOS #6: Pagination DemystifiedRambler.iOS #6: Pagination Demystified
Rambler.iOS #6: Pagination Demystified
 
Rambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPERRambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPER
 
Rambler.iOS #5: VIPER a la Rambler
Rambler.iOS #5: VIPER a la RamblerRambler.iOS #5: VIPER a la Rambler
Rambler.iOS #5: VIPER a la Rambler
 

Recently uploaded

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraDeakin University
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 

Recently uploaded (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Artificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning eraArtificial intelligence in the post-deep learning era
Artificial intelligence in the post-deep learning era
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 

Rambler.iOS #5: Разбираем Massive View Controller

  • 1. Александр Сычев Разработчик iOS RAMBLER.iOS V Как разобрать Massive View Controller и сделать из него VIPER-модуль
  • 2. Massive View Controller -> VIPER Проблемы Massive View Controller Примеры Немного статистики
  • 3. Massive View Controller -> VIPER Проблемы Massive View Controller Примеры Немного статистики
  • 4. Massive View Controller -> VIPER Dark Massive View Controller Light VIPER
  • 5. Massive View Controller -> VIPER Model View Controller ModelView Controller Mediator Strategy User action Update Update Notify
  • 6. Massive View Controller -> VIPER Massive View Controller
  • 7. Massive View Controller -> VIPER •Высокая сложность поддержки и развития •Высокий порог вхождения •Слабо тестируем •Невозможно переиспользовать •Редактор притормаживает на 5 000 строк кода 😃 Недостатки Massive View Controller
  • 9. Massive View Controller -> VIPER Проблемы Massive View Controller Примеры Немного статистики
  • 12. Massive View Controller -> VIPER Переход между экранами
  • 13. Massive View Controller -> VIPER View Presenter Interactor Router Переход между экранами
  • 14. Massive View Controller -> VIPER @protocol AGMainMenuControllerViewOutput <NSObject> - (void)showMenuSectionWithType:(MainMenuSectionType)sectionType fromViewController:(UIViewController *)viewController; @end View Presenter Interactor Router
  • 15. Massive View Controller -> VIPER View Presenter Interactor Router Handle event @protocol AGMainMenuControllerViewOutput <NSObject> - (void)showMenuSectionWithType:(MainMenuSectionType)sectionType fromViewController:(UIViewController *)viewController; @end
  • 16. Massive View Controller -> VIPER - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSInteger index = indexPath.row; [self.output showMenuSectionWithType:index fromViewController:self]; } View Presenter Interactor Router Handle event
  • 17. Massive View Controller -> VIPER - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSInteger index = indexPath.row; [self.output showMenuSectionWithType:index fromViewController:self]; } View Presenter Interactor Router Handle eventTable delegate
  • 18. Massive View Controller -> VIPER @protocol AGMainMenuRouterInput <NSObject> - (void)showCityFromViewController:(UIViewController *)vcS; - (void)showPlacesFromViewController:(UIViewController *)vcS; - (void)showReferenceBookFromViewController:(UIViewController *)vcS; @end View Presenter Interactor Router Handle eventTable delegate
  • 19. Massive View Controller -> VIPER @protocol AGMainMenuRouterInput <NSObject> - (void)showCityFromViewController:(UIViewController *)vcS; - (void)showPlacesFromViewController:(UIViewController *)vcS; - (void)showReferenceBookFromViewController:(UIViewController *)vcS; @end View Presenter Interactor Router Handle eventTable delegate Module routing
  • 20. Massive View Controller -> VIPER - (void)showMenuSectionWithType:(MainMenuSectionType)sectionType fromViewController:(UIViewController *)viewController { switch (sectionType) { <Call RouterInput methods> } } View Presenter Interactor Router Handle eventTable delegate Module routing
  • 21. Massive View Controller -> VIPER - (void)showMenuSectionWithType:(MainMenuSectionType)sectionType fromViewController:(UIViewController *)viewController { switch (sectionType) { <Call RouterInput methods> } } View Presenter Interactor Router Handle eventTable delegate Module routing Call Router
  • 22. Massive View Controller -> VIPER - (void)showCityFromViewController:(UIViewController *)vcS { UIStoryboard *sb = <Load storyboard>; UIViewController *vcD = <Instantiate ViewController>; [vcS.navigationController pushViewController:vcD animated:YES]; } View Presenter Interactor Router Handle eventTable delegate Module routing Call Router
  • 23. Massive View Controller -> VIPER Переход между экранами Massive View Controller VIPER
  • 24. Massive View Controller -> VIPER Чтение данных
  • 25. Massive View Controller -> VIPER Чтение данных View Presenter Interactor Router
  • 26. Massive View Controller -> VIPER @protocol AGMainMenuControllerViewOutput <NSObject> - (void)obtainQuarters; @end View Presenter Interactor Router
  • 27. Massive View Controller -> VIPER View Presenter Interactor Router @protocol AGMainMenuControllerViewOutput <NSObject> - (void)obtainQuarters; @end Handle event
  • 28. Massive View Controller -> VIPER - (void)viewDidLoad { [super viewDidLoad]; [self.output obtainQuarters]; } View Presenter Interactor Router Handle event
  • 29. Massive View Controller -> VIPER - (void)viewDidLoad { [super viewDidLoad]; [self.output obtainQuarters]; } View Presenter Interactor Router Handle eventAsk for data
  • 30. Massive View Controller -> VIPER - (void)obtainQuarters { [self.view showSpinners]; [self.interactor loadQuarters]; } View Presenter Interactor Router Handle eventAsk for data
  • 31. Massive View Controller -> VIPER - (void)obtainQuarters { [self.view showSpinners]; [self.interactor loadQuarters]; } View Presenter Interactor Router Handle eventAsk for data Call Interactor
  • 32. Massive View Controller -> VIPER - (void)loadQuarters { <Prepare loading request> NSArray *quarters = [AGQuarter MR_findAllSortedBy:sortTerm inContext:context]; NSArray *ponsoQuarters = [self createPlainObjectsFrom:quarters]; [self.output loadedQuarters:ponsoQuarters]; } View Presenter Interactor Router Handle eventAsk for data Call Interactor
  • 33. Massive View Controller -> VIPER - (void)loadQuarters { <Prepare loading request> NSArray *quarters = [AGQuarter MR_findAllSortedBy:sortTerm inContext:context]; NSArray *ponsoQuarters = [self createPlainObjectsFrom:quarters]; [self.output loadedQuarters:ponsoQuarters]; } View Presenter Interactor Router Handle eventAsk for data Call Interactor Load data
  • 34. Massive View Controller -> VIPER - (void)loadedQuarters:(NSArray *)quarters { [self.view hideSpinners]; [self.view handleObtainedQuarters:quarters]; } View Presenter Interactor Router Handle eventAsk for data Call Interactor Load data
  • 35. Massive View Controller -> VIPER - (void)loadedQuarters:(NSArray *)quarters { [self.view hideSpinners]; [self.view handleObtainedQuarters:quarters]; } View Presenter Interactor Router Handle eventAsk for data Call Interactor Load data Prepare data
  • 36. Massive View Controller -> VIPER View Presenter Interactor Router Handle eventAsk for data Call Interactor Load data Prepare data - (void)handleObtainedQuarters:(NSArray *)quarters { <Display quarters> }
  • 37. Massive View Controller -> VIPER - (void)handleObtainedQuarters:(NSArray *)quarters { <Display quarters> } View Presenter Interactor Router Handle eventAsk for data Call Interactor Load data Prepare data Display data
  • 38. Massive View Controller -> VIPER Чтение данных Massive View Controller VIPER
  • 39. Massive View Controller -> VIPER Конфигурация объектов
  • 40. Massive View Controller -> VIPER AssemblyVIPER-модуль Конфигурация объектов
  • 41. Massive View Controller -> VIPER @interface AGMainMenuInteractor : NSObject <AGMainMenuInteractorInput> @property (weak) id<AGMainMenuInteractorOutput> output; @property (strong) id<AGImageLocalCacheManager> imageLocalCacheManager; @end AssemblyVIPER-модуль
  • 42. Massive View Controller -> VIPER @interface AGMainMenuInteractor : NSObject <AGMainMenuInteractorInput> @property (weak) id<AGMainMenuInteractorOutput> output; @property (strong) id<AGImageLocalCacheManager> imageLocalCacheManager; @end AssemblyVIPER-модуль Load image
  • 43. Massive View Controller -> VIPER - (AGMainMenuInteractor *)interactorMainMenu { return [TyphoonDefinition withClass:[AGMainMenuInteractor class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(imageLocalCacheManager) with:[self.coreHelpersAssembly imageLocalCacheManager]]; }]; } AssemblyVIPER-модуль Load image
  • 44. Massive View Controller -> VIPER - (AGMainMenuInteractor *)interactorMainMenu { return [TyphoonDefinition withClass:[AGMainMenuInteractor class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(imageLocalCacheManager) with:[self.coreHelpersAssembly imageLocalCacheManager]]; }]; } AssemblyVIPER-модуль Load image Configure Module
  • 45. Massive View Controller -> VIPER - (id<AGImageLocalCacheManager>)imageLocalCacheManager { return [TyphoonDefinition withClass:[AGImageLocalCacheManagerImplementation class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(managerWithFileManager:) parameters:^(TyphoonMethod *initializer) { [initializer injectParameterWith:[self fileManager]]; }]; }]; } CoreHelpersAssembly
  • 46. Massive View Controller -> VIPER AssemblyVIPER-модуль Load image Конфигурация объектов - (void)loadBackgroundImage { UIImage *guideBackgroundImage = [self.imageLocalCacheManager loadImageWithImageId:guide.backgroundImage.photoId]; [self.output loadedBackgroundImage:guideBackgroundImage]; } Configure Module
  • 47. Massive View Controller -> VIPER AssemblyVIPER-модуль Use Core HelpersLoad image Конфигурация объектов - (void)loadBackgroundImage { UIImage *guideBackgroundImage = [self.imageLocalCacheManager loadImageWithImageId:guide.backgroundImage.photoId]; [self.output loadedBackgroundImage:guideBackgroundImage]; } Configure Module - (void)loadBackgroundImage { UIImage *guideBackgroundImage = [self.imageLocalCacheManager loadImageWithImageId:guide.backgroundImage.photoId]; [self.output loadedBackgroundImage:guideBackgroundImage]; }
  • 48. Massive View Controller -> VIPER Конфигурация объектов Massive View Controller VIPER
  • 49. Massive View Controller -> VIPER View Interactor Presenter Router Assembly
  • 50. Massive View Controller -> VIPER View Interactor Presenter Router Assembly
  • 51. Massive View Controller -> VIPER Трудозатраты 24 человеко-часа
  • 52. Massive View Controller -> VIPER Проблемы Massive View Controller Примеры Немного статистики
  • 53. Massive View Controller -> VIPER Статистика MVC VIPER R1 ~9,3K / 0,175K ~18K / 0,58K R2 ~7,6K / 0,54K ~1,1K / 0,55K R3 ~3,8K / 0,38K ~8,4K / 0,53K
  • 54. Massive View Controller -> VIPER > 1,5 раза
  • 55. Massive View Controller -> VIPER Выводы VIPER MVC
  • 56. Massive View Controller -> VIPER Спасибо за внимание!