Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Typhoon Explained
Egor Tolstoy
June 04, 2016
Technology
1
140
Typhoon Explained
Slides for Mobius Conference 2016.
Egor Tolstoy
June 04, 2016
Tweet
Share
More Decks by Egor Tolstoy
See All by Egor Tolstoy
etolstoy
0
32
etolstoy
1
190
etolstoy
0
190
etolstoy
0
55
etolstoy
1
260
etolstoy
0
63
etolstoy
0
510
etolstoy
1
190
etolstoy
1
150
Other Decks in Technology
See All in Technology
waka
5
2.8k
kanaugust
PRO
0
110
lain21
14
5.3k
legalforce
PRO
0
190
thorstenhans
0
100
tatsy
2
440
katsumataryo
3
830
kanaugust
PRO
0
120
comucal
PRO
0
310
lmi
5
3.7k
sei88888
5
450
tsuyo
0
500
Featured
See All Featured
schacon
147
6.7k
mojombo
359
62k
pauljervisheath
195
15k
bryan
100
11k
mza
80
4.2k
geeforr
333
29k
jonrohan
1021
390k
chrislema
173
14k
jponch
103
5.1k
ddemaree
273
31k
jlugia
217
16k
holman
288
130k
Transcript
T yphoon explained Egor T olstoy @igrekde
2
3
4 Creating new project
5
6
7
8 - loadBarbershops - cacheBarbershops - reloadTableData - loadBarbershops -
cacheBarbershops - reloadTableData
9 BarberService
10 BarberService FakeBarberService
11 BarberService FakeBarberService VC 3 VC 4 VC 5 VC
6
12 @interface BarberListViewController() @property (nonatomic, strong) BarberServiceMain *service; @end
13 <BarberService> BarberServiceMain BarberServiceFake
14 @interface BarberListViewController() @property (nonatomic, strong) id<BarberService> service; @end
15 <BarberService> BarberServiceMain Assembly содержат создает создает VC 3 VC
4 VC 5
16 <BarberService> FakeBarberService Assembly содержат создает создает VC 3 VC
4 VC 5
Assembly Typhoon
18 Устройство Typhoon на трех пальцах Юзкейсы Легенды и мифы
19 Under the Hood
20 BarberViewController MapViewController BarberServiceMain BarberServiceFake Typhoon Component Factory componentForKey: Объект
21 BarberServiceMain type: (Class)BarberServiceMain key: barberServiceMainDefinition
22 BarberServiceMain type: (Class)BarberServiceMain key: barberServiceMainDefinition NetworkClient type: (Class)NetworkClient key:
networkClientDefinition BarberParser type: (Class)BarberParser key: networkClientDefinition
23 [BarberServiceMain new] [NetworkClient new] [BarberParser new] [BarberViewController new] [storyboard
instantiateViewController:]
24 Property Injection
25 <BarberService> BarberServiceMain
26 BarberListViewController type: (Class)BarberListViewController key: barberListViewControllerDefinition BarberService type: (Class)BarberServiceMain key:
barberServiceMainDefinition BarberListAssembly
27 @implementation BarberListAssembly - (BarberListViewController *)barberListViewControllerDefinition { return [TyphoonDefinition withClass:[BarberListViewController
class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(service) with:[self barberService]]; }]; } - (id<BarberService>)barberServiceMainDefinition { return [TyphoonDefinition withClass:[BarberServiceMain class]]; } @end
28 Modularizing Assemblies
29 <BarberService> BarberServiceMain <BarberService> BarberServiceMain
30 BarberListViewController BarberService BarberListAssembly BarberMapViewController BarberService BarberMapAssembly BarberService ServiceAssembly
31 @interface BarberListAssembly @property (nonatomic, strong) TyphoonAssembly<ServiceAssembly> *serviceAssembly; @end @implementation
BarberListAssembly - (BarberListViewController *)barberListViewControllerDefinition { return [TyphoonDefinition withClass:[BarberListViewController class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(service) with:[self.serviceAssembly barberService]]; }]; } @end
32 Scopes
33 <LocationService> LocationServiceMain CLLocationManager
34 BarberListViewController LocationService BarberListAssembly BarberMapViewController LocationService BarberMapAssembly LocationService ServiceAssembly scope:
TyphoonScopeSingleton
35 TyphoonScopeObjectGraph TyphoonScopePrototype TyphoonScopeSingleton TyphoonScopeLazySingleton TyphoonScopeWeakSingleton
36 @implementation ServiceAssembly - (id<BarberService>)barberServiceMainDefinition { return [TyphoonDefinition withClass:[BarberServiceMain class]
configuration:^(TyphoonDefinition *definition) { definition.scope = TyphoonScopeSingleton; }]; } @end
37 UI Injections
38 BarberViewController MapViewController BarberServiceMain BarberServiceFake Typhoon Component Factory componentForClass: [BarberViewController
class] [BarberViewController new]
39 JiggleAnimator Calculator1 Calculator2
40
41 @implementation ReusableViewAssembly - (MoustacheView *)moustacheView { return [TyphoonDefinition withClass:[MoustacheView
class] configuration:^(TyphoonDefinition *definition) { [definition useInitializer:@selector(view)]; [definition injectProperty:[self animator]]; }]; } @end @implementation MoustacheView + (MoustacheView *)view { return [[[NSBundle mainBundle] loadNibNamed:@"MoustacheView"]; } @end
42 Method Injection
43 MoustacheManager
44 @implementation ReusableViewAssembly - (MoustacheView *)moustacheView { return [TyphoonDefinition withClass:[MoustacheView
class] configuration:^(TyphoonDefinition *definition) { ... [definition injectProperty:[self manager]]; [definition injectMethod: @selector(subscribeToManager)]; }]; } @end @implementation MoustacheView - (void)subscribeToManager { [self.manager addMoustache:self]; } @end
45 Factories, attributes, options
46 Москва Питер
47 <ServiceFactory> BarberServiceMoscow BarberServicePiter ServiceAssembly Москва Питер
48 <ServiceFactory> BarberServiceMoscow BarberServicePiter ServiceAssembly Москва Питер
49 <ServiceFactory> BarberServiceMoscow BarberServicePiter ServiceAssembly
50 @interface BarberListAssembly @property (nonatomic, strong) TyphoonAssembly<ServiceAssembly> *serviceAssembly; @end @implementation
BarberListAssembly - (BarberListViewController *)barberListViewControllerDefinition { return [TyphoonDefinition withClass:[BarberListViewController class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(factory) with:[self.serviceAssembly]]; }]; } @end
51 @implementation ServiceAssembly - (id<BarberService>)barberServiceForCity:(NSString *)city { return [TyphoonDefinition withOption:city
matcher:^(TyphoonOptionMatcher *matcher) { [matcher caseEqual:@"Moscow" use:[self moscowBarberService]]; [matcher caseEqual:@"Piter" use:[self piterBarberService]]; }]; } @end
52 [matcher caseEqual:@"Moscow" use:[self moscowBarberService]]; [matcher caseEqual:@"Piter" use:[self piterBarberService]];
53 Config
54 AppDelegate TyphoonConfig(flurryKey) ApplicationAssembly TyphoonConfig(googleKey) { "config": { "flurryKey": "abcdef",
"googleKey" : "ghijkl" } } config.plist
55 @implementation ApplicationAssembly - (AppDelegate *)appDelegate { return [TyphoonDefinition withClass:[AppDelegate
class] configuration:^(TyphoonDefinition *definition) { [definition injectProperty:@selector(flurryKey) with:TyphoonConfig(@"config.flurryKey")]; [definition injectProperty:@selector(googleKey) with:TyphoonConfig(@"config.googleKey")]; }]; } @end
56 NSURL(http://mobiusconf.ru) MyStyle(#8732A9;17;HelveticeNeue-Regular)
57 PostCategories(top#cyr,0,cyr,cyr| top#noncyr,1,noncyr,noncyr)
58 Instance Postprocessor
59
60 BarberListRouter <Router> -openScreenWithIdentifier:(NSString *)identifier
61 RouterDecorator BarberListRouter Flurry/Google <Router> identifier identifier
62 @implementation AnalyticsPostProcessor - (id)postProcessInstance:(id)instance { if ([instance conformsToProtocol:@protocol(Router)]) {
return [DecoratedRouter decoratedRouterWith:instance]; } return instance; } @end
63 Integration T esting
64 <BarberService> BarberServiceMain <NetworkClient> NetworkClientMain
65 <BarberService> BarberServiceMain <NetworkClient> NetworkClientFake
66 BarberListViewController BarberService BarberListAssembly BarberService ServiceAssembly NetworkClient NetworkClientMain NetworkAssembly
67 BarberListViewController BarberService BarberListAssembly BarberService ServiceAssembly NetworkClient NetworkClientFake NetworkAssembly
68 - (void)setUp { ... TyphoonPatcher *patcher = [[TyphoonPatcher alloc]
init]; [patcher patchDefinitionWithSelector:@selector(networkClient) withObject:^id{ return [NetworkClientFake new]; }]; [barberListAssembly attachPostProcessor:patcher]; }
69 Autowiring
70 @interface BarberListViewControllerTests @property (nonatomic, strong) BarberListViewController *viewController; @property (nonatomic,
strong) id<BarberService> service; @property (nonatomic, strong) MoustacheView *view; @end - (void)setUp { ... self.viewController = [barberListAssembly viewController]; self.service = [serviceAssembly barberService]; self.view = [moustacheViewAssembly moustacheView]; }
71 @interface BarberListViewControllerTests @property (nonatomic, strong) InjectedClass(BarberListViewController) viewController; @property (nonatomic,
strong) InjectedProtocol(BarberService) service; @property (nonatomic, strong) InjectedClass(MoustacheView) view; @end - (void)setUp { ... [barberListAssembly inject:self]; }
72 Assembly Unit T ests
73 - (void)testThatAssemblyCreatesRouter { // given Class targetClass = [SettingsRouter
class]; NSArray *dependencies = @[ RamblerSelector(transitionHandler) ]; // when id result = [self.assembly routerSettingsModule]; // then [self verifyTargetDependency:result withClass:targetClass dependencies:dependencies]; }
74 https://github.com/rambler-ios/ RamblerTyphoonUtils
75 Legends
76 Typhoon работает со Swift
77 Но… там же свиззлинг!
78 Высокий порог вхождения
79 Сильное влияние на отладку
80 Но я же могу велосипедить... %
81 Finally
82 Устройство Typhoon на трех пальцах Юзкейсы Легенды и мифы
Egor T olstoy @igrekde Any magic, sufficiently analyzed is indistinguishable
from technology igrekde@gmail.com