56
Александр Сычев Разработчик iOS RAMBLER.iOS V Как разобрать Massive View Controller и сделать из него VIPER-модуль

Разбираем Massive View Controller

Embed Size (px)

Citation preview

Page 1: Разбираем Massive View Controller

Александр Сычев Разработчик iOS

RAMBLER.iOS V

Как разобрать Massive View Controller и сделать из него VIPER-модуль

Page 2: Разбираем Massive View Controller

Massive View Controller -> VIPER

Проблемы Massive View Controller

Примеры

Немного статистики

Page 3: Разбираем Massive View Controller

Massive View Controller -> VIPER

Проблемы Massive View Controller

Примеры

Немного статистики

Page 4: Разбираем Massive View Controller

Massive View Controller -> VIPER

Dark Massive View Controller Light VIPER

Page 5: Разбираем Massive View Controller

Massive View Controller -> VIPER

Model View Controller

ModelView

Controller

Mediator Strategy

User action

Update

Update

Notify

Page 6: Разбираем Massive View Controller

Massive View Controller -> VIPER

Massive View Controller

Page 7: Разбираем Massive View Controller

Massive View Controller -> VIPER

•Высокая сложность поддержки и развития

•Высокий порог вхождения

•Слабо тестируем

•Невозможно переиспользовать

•Редактор притормаживает на 5 000 строк кода 😃

Недостатки Massive View Controller

Page 8: Разбираем Massive View Controller

Massive View Controller -> VIPER

Page 9: Разбираем Massive View Controller

Massive View Controller -> VIPER

Проблемы Massive View Controller

Примеры

Немного статистики

Page 10: Разбираем Massive View Controller

Massive View Controller -> VIPER

Page 11: Разбираем Massive View Controller

Massive View Controller -> VIPER

Page 12: Разбираем Massive View Controller

Massive View Controller -> VIPER

Переход между экранами

Page 13: Разбираем Massive View Controller

Massive View Controller -> VIPER

View Presenter Interactor Router

Переход между экранами

Page 14: Разбираем Massive View Controller

Massive View Controller -> VIPER

@protocol AGMainMenuControllerViewOutput <NSObject>

- (void)showMenuSectionWithType:(MainMenuSectionType)sectionType fromViewController:(UIViewController *)viewController;

@end

View Presenter Interactor Router

Page 15: Разбираем Massive View Controller

Massive View Controller -> VIPER

View Presenter Interactor Router

Handle event

@protocol AGMainMenuControllerViewOutput <NSObject>

- (void)showMenuSectionWithType:(MainMenuSectionType)sectionType fromViewController:(UIViewController *)viewController;

@end

Page 16: Разбираем Massive View Controller

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

Page 17: Разбираем Massive View Controller

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

Page 18: Разбираем Massive View Controller

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

Page 19: Разбираем Massive View Controller

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

Page 20: Разбираем Massive View Controller

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

Page 21: Разбираем Massive View Controller

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

Page 22: Разбираем Massive View Controller

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

Page 23: Разбираем Massive View Controller

Massive View Controller -> VIPER

Переход между экранами

Massive View Controller VIPER

Page 24: Разбираем Massive View Controller

Massive View Controller -> VIPER

Чтение данных

Page 25: Разбираем Massive View Controller

Massive View Controller -> VIPER

Чтение данных

View Presenter Interactor Router

Page 26: Разбираем Massive View Controller

Massive View Controller -> VIPER

@protocol AGMainMenuControllerViewOutput <NSObject>

- (void)obtainQuarters;

@end

View Presenter Interactor Router

Page 27: Разбираем Massive View Controller

Massive View Controller -> VIPER

View Presenter Interactor Router

@protocol AGMainMenuControllerViewOutput <NSObject>

- (void)obtainQuarters;

@end

Handle event

Page 28: Разбираем Massive View Controller

Massive View Controller -> VIPER

- (void)viewDidLoad { [super viewDidLoad]; [self.output obtainQuarters];}

View Presenter Interactor Router

Handle event

Page 29: Разбираем Massive View Controller

Massive View Controller -> VIPER

- (void)viewDidLoad { [super viewDidLoad]; [self.output obtainQuarters];}

View Presenter Interactor Router

Handle eventAsk for data

Page 30: Разбираем Massive View Controller

Massive View Controller -> VIPER

- (void)obtainQuarters { [self.view showSpinners]; [self.interactor loadQuarters];}

View Presenter Interactor Router

Handle eventAsk for data

Page 31: Разбираем Massive View Controller

Massive View Controller -> VIPER

- (void)obtainQuarters { [self.view showSpinners]; [self.interactor loadQuarters];}

View Presenter Interactor Router

Handle eventAsk for data

Call Interactor

Page 32: Разбираем Massive View Controller

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

Page 33: Разбираем Massive View Controller

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

Page 34: Разбираем Massive View Controller

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

Page 35: Разбираем Massive View Controller

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

Page 36: Разбираем Massive View Controller

Massive View Controller -> VIPER

View Presenter Interactor Router

Handle eventAsk for data

Call Interactor

Load data

Prepare data

- (void)handleObtainedQuarters:(NSArray *)quarters { <Display quarters>}

Page 37: Разбираем Massive View Controller

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

Page 38: Разбираем Massive View Controller

Massive View Controller -> VIPER

Чтение данных

Massive View Controller VIPER

Page 39: Разбираем Massive View Controller

Massive View Controller -> VIPER

Конфигурация объектов

Page 40: Разбираем Massive View Controller

Massive View Controller -> VIPER

AssemblyVIPER-модуль

Конфигурация объектов

Page 41: Разбираем Massive View Controller

Massive View Controller -> VIPER

@interface AGMainMenuInteractor : NSObject <AGMainMenuInteractorInput>

@property (weak) id<AGMainMenuInteractorOutput> output;

@property (strong) id<AGImageLocalCacheManager> imageLocalCacheManager;

@end

AssemblyVIPER-модуль

Page 42: Разбираем Massive View Controller

Massive View Controller -> VIPER

@interface AGMainMenuInteractor : NSObject <AGMainMenuInteractorInput>

@property (weak) id<AGMainMenuInteractorOutput> output;

@property (strong) id<AGImageLocalCacheManager> imageLocalCacheManager;

@end

AssemblyVIPER-модуль

Load image

Page 43: Разбираем Massive View Controller

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

Page 44: Разбираем Massive View Controller

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

Page 45: Разбираем Massive View Controller

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

Page 46: Разбираем Massive View Controller

Massive View Controller -> VIPER

AssemblyVIPER-модуль

Load image

Конфигурация объектов- (void)loadBackgroundImage { UIImage *guideBackgroundImage = [self.imageLocalCacheManager loadImageWithImageId:guide.backgroundImage.photoId]; [self.output loadedBackgroundImage:guideBackgroundImage];}

Configure Module

Page 47: Разбираем Massive View Controller

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];}

Page 48: Разбираем Massive View Controller

Massive View Controller -> VIPER

Конфигурация объектов

Massive View Controller VIPER

Page 49: Разбираем Massive View Controller

Massive View Controller -> VIPER

View

Interactor

Presenter

Router

Assembly

Page 50: Разбираем Massive View Controller

Massive View Controller -> VIPER

View

Interactor

Presenter

Router

Assembly

Page 51: Разбираем Massive View Controller

Massive View Controller -> VIPER

Трудозатраты

24 человеко-часа

Page 52: Разбираем Massive View Controller

Massive View Controller -> VIPER

Проблемы Massive View Controller

Примеры

Немного статистики

Page 53: Разбираем Massive View Controller

Massive View Controller -> VIPER

Статистика

MVC VIPERR1 ~9,3K / 0,175K ~18K / 0,58KR2 ~7,6K / 0,54K ~1,1K / 0,55KR3 ~3,8K / 0,38K ~8,4K / 0,53K

Page 54: Разбираем Massive View Controller

Massive View Controller -> VIPER

> 1,5 раза

Page 55: Разбираем Massive View Controller

Massive View Controller -> VIPER

Выводы

VIPER MVC

Page 56: Разбираем Massive View Controller

Massive View Controller -> VIPER

Спасибо за внимание!