Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Typhoon Explained
Search
Egor Tolstoy
June 04, 2016
Technology
1
180
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
310
OKR без хайпа
etolstoy
1
280
OKR: инструкция по применению
etolstoy
0
360
Avito Mobile: State of the Union
etolstoy
0
110
Developer Experience: The Art of Building Spaceships
etolstoy
1
590
Выступайте
etolstoy
0
130
Улучшая performance review
etolstoy
0
1.4k
May the Code Review be with you [English]
etolstoy
1
220
May the Code Review be with you [Russian]
etolstoy
1
190
Other Decks in Technology
See All in Technology
宇宙最速のランチRecap LT会(AWS re:Invent 2024)
watany
1
340
密着! Bedrockerがre:Invent 2024で過ごした5日間を紹介
minorun365
PRO
3
230
LY Accessibility Guidelines @fukuoka_a11yconf_前夜祭
lycorptech_jp
PRO
1
150
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
5
52k
Oracle Base Database Service:サービス概要のご紹介
oracle4engineer
PRO
0
15k
属人化したE2E自動テストを ひも解く
honamin09
1
110
.NET のUnified AI Building Blocks 入門...!
okazuki
0
190
AWS認定試験の長文問題を早く解くコツ
keke1234ke
0
170
asumikamというカンファレンスオーガナイザの凄さを語る / The Brilliance of Asumikam
tomzoh
1
290
プルリクが全てじゃない!実は喜ばれるOSS貢献の方法8選
tkikuc
17
2.3k
Explain EXPLAIN
keiko713
10
2.7k
スパイクアクセス対策としての pitchfork 導入
riseshia
0
130
Featured
See All Featured
Art, The Web, and Tiny UX
lynnandtonic
297
20k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
What's in a price? How to price your products and services
michaelherold
243
12k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
A better future with KSS
kneath
238
17k
How to Ace a Technical Interview
jacobian
276
23k
Bash Introduction
62gerente
608
210k
Rails Girls Zürich Keynote
gr2m
94
13k
How to Think Like a Performance Engineer
csswizardry
21
1.2k
YesSQL, Process and Tooling at Scale
rocio
169
14k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.3k
Why Our Code Smells
bkeepers
PRO
334
57k
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
[email protected]