SlideShare a Scribd company logo
Александр Сычев
Разработчик 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&Co
e-Legion
 
Viper
ViperViper
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
mdc11
 
Conductor vs Fragments
Conductor vs FragmentsConductor vs Fragments
Backbone.js
Backbone.jsBackbone.js
Backbone.js
VO Tho
 
Introduction to Angular JS
Introduction to Angular JSIntroduction to Angular JS
Introduction to Angular JS
Santhosh Kumar Srinivasan
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
Tudor Barbu
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
WO Community
 
D2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRollerD2W Branding Using jQuery ThemeRoller
D2W Branding Using jQuery ThemeRoller
WO 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
 
Spring 4 Web App
Spring 4 Web AppSpring 4 Web App
Spring 4 Web App
Rossen Stoyanchev
 
Infrastructure as Code 삽질기
Infrastructure as Code 삽질기Infrastructure as Code 삽질기
Infrastructure as Code 삽질기
Changwan Jun
 
Practical ERSync
Practical ERSyncPractical ERSync
Practical ERSync
WO Community
 
Model-View-Controller: Tips&Tricks
Model-View-Controller: Tips&TricksModel-View-Controller: Tips&Tricks
Model-View-Controller: Tips&Tricks
Ciklum Ukraine
 
Using ReactJS in AngularJS
Using ReactJS in AngularJSUsing ReactJS in AngularJS
Using ReactJS in AngularJS
Boris 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 Standard
Immo 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, JBoss
mfrancis
 
Nuxt.JS Introdruction
Nuxt.JS IntrodructionNuxt.JS Introdruction
Nuxt.JS Introdruction
David Ličen
 
Drupal point of vue
Drupal point of vueDrupal point of vue
Drupal point of vue
David 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: Подмодули в VIPER
RAMBLER&Co
 
Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101Rambler.iOS #7: Интернет-эквайринг 101
Rambler.iOS #7: Интернет-эквайринг 101
RAMBLER&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: Мастер-класс по Dip
RAMBLER&Co
 
Rambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеровRambler.iOS #8: Как не стать жертвой бэкендеров
Rambler.iOS #8: Как не стать жертвой бэкендеров
RAMBLER&Co
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: Promises
RAMBLER&Co
 
RDSDataSource: OCLint
RDSDataSource: OCLintRDSDataSource: OCLint
RDSDataSource: OCLint
RAMBLER&Co
 
RDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDKRDSDataSource: Автогенерация документации для SDK
RDSDataSource: Автогенерация документации для SDK
RAMBLER&Co
 
Rambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxprojRambler.iOS #6: Не рычите на pbxproj
Rambler.iOS #6: Не рычите на pbxproj
RAMBLER&Co
 
RDSDataSource: YapDatabase
RDSDataSource: YapDatabaseRDSDataSource: YapDatabase
RDSDataSource: YapDatabase
RAMBLER&Co
 
RDSDataSource: App Thinning
RDSDataSource: App ThinningRDSDataSource: App Thinning
RDSDataSource: App Thinning
RAMBLER&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: Чистые тесты на Swift
RAMBLER&Co
 
RDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperiencedRDSDataSource: iOS Reverse Engineering for inexperienced
RDSDataSource: iOS Reverse Engineering for inexperienced
RAMBLER&Co
 
Rambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и SwiftRambler.iOS #5: VIPER и Swift
Rambler.iOS #5: VIPER и Swift
RAMBLER&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 Pattern
goodfriday
 
[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern[22]Efficient and Testable MVVM pattern
[22]Efficient and Testable MVVM pattern
NAVER Engineering
 
Sexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroidsSexy Architecting. VIPER: MVP on steroids
Sexy Architecting. VIPER: MVP on steroids
Dmytro 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
 
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
Somkiat Khitwongwattana
 
Asp.Net MVC Framework Design Pattern
Asp.Net MVC Framework Design PatternAsp.Net MVC Framework Design Pattern
Asp.Net MVC Framework Design Pattern
maddinapudi
 
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
Maxim Gaponov
 
점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정점진적인 레거시 웹 애플리케이션 개선 과정
점진적인 레거시 웹 애플리케이션 개선 과정
Arawn Park
 
Mvc - Titanium
Mvc - TitaniumMvc - Titanium
Mvc - Titanium
Prawesh Shrestha
 
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
 
easemesh-architecture.pptx
easemesh-architecture.pptxeasemesh-architecture.pptx
easemesh-architecture.pptx
SumanthChinthagunta
 
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
Visual Engineering
 
ASP.NET MVC Internals
ASP.NET MVC InternalsASP.NET MVC Internals
ASP.NET MVC Internals
Vitaly Baum
 
Android securitybyexample
Android securitybyexampleAndroid securitybyexample
Android securitybyexample
Pragati Rai
 
ASP.NET Internals
ASP.NET InternalsASP.NET Internals
ASP.NET Internals
GoSharp
 
SFNode 01-2018 - Aquarium control
SFNode 01-2018 - Aquarium controlSFNode 01-2018 - Aquarium control
SFNode 01-2018 - Aquarium control
Bryan 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 architecture
Toru 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: Основы LLVM
RAMBLER&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 memory
RAMBLER&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 JavaScriptCore
RAMBLER&Co
 
RDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOSRDSDataSource: Плюрализация в iOS
RDSDataSource: Плюрализация в iOS
RAMBLER&Co
 
RDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwiftRDSDataSource: Flux, Redux, ReSwift
RDSDataSource: Flux, Redux, ReSwift
RAMBLER&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 Demystified
RAMBLER&Co
 
Rambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPERRambler.iOS #5: TDD и VIPER
Rambler.iOS #5: TDD и VIPER
RAMBLER&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 Rambler
RAMBLER&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

Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
TIPNGVN2
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Zilliz
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
DianaGray10
 

Recently uploaded (20)

Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Data structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdfData structures and Algorithms in Python.pdf
Data structures and Algorithms in Python.pdf
 
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
Introducing Milvus Lite: Easy-to-Install, Easy-to-Use vector database for you...
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6UiPath Test Automation using UiPath Test Suite series, part 6
UiPath Test Automation using UiPath Test Suite series, part 6
 

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 Спасибо за внимание!