Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Typhoon Explained
Search
Egor Tolstoy
June 04, 2016
Technology
1
170
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
260
OKR без хайпа
etolstoy
1
250
OKR: инструкция по применению
etolstoy
0
280
Avito Mobile: State of the Union
etolstoy
0
86
Developer Experience: The Art of Building Spaceships
etolstoy
1
500
Выступайте
etolstoy
0
94
Улучшая performance review
etolstoy
0
1.2k
May the Code Review be with you [English]
etolstoy
1
210
May the Code Review be with you [Russian]
etolstoy
1
180
Other Decks in Technology
See All in Technology
XRミーティング 2024-03-20
1ftseabass
PRO
0
100
オブジェクト指向CSSが叶えたかったことと、CSSのいま / The aims of Object-oriented CSS and the current state of CSS usage
shinkufencer
11
3.7k
Evolutionary Optimization of Model Merging Recipes
fuyu_quant0
3
560
MongoDB Atlas Vectorsearchではじめる生成AIアプリ開発
chie8842
3
510
VSCode上からSlackにメッセージを送る拡張機能を作っている話
ebarakazuhiro
0
130
10分でわかるfreeeのQA
freee
0
260
BDD(Cucumber)コミュニティが無料提供しているコンテンツの紹介と現在起きている危機
nihonbuson
4
750
Autify Company Deck
autifyhq
1
30k
中学生でもわかる深層学習
e869120
13
4.2k
これまでのキャリアとこれからMLエンジニアとしてどう動くか
masatakashiwagi
1
770
生成AI・LLM時代における 機械学習エンジニアとしてのキャリア戦略・開発戦略 / my-career-and-development-strategies-for-ml-engineer-2024
yuya4
4
960
ハイパフォーマンスな組織をつくるための開発生産性の考え方 / developer-productivity-high-performer-link-and-motivation
lmi
3
280
Featured
See All Featured
Web development in the modern age
philhawksworth
201
10k
Designing for Performance
lara
601
67k
Building a Scalable Design System with Sketch
lauravandoore
455
32k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
355
22k
The Invisible Customer
myddelton
114
12k
Code Reviewing Like a Champion
maltzj
512
39k
How To Stay Up To Date on Web Technology
chriscoyier
781
250k
Into the Great Unknown - MozCon
thekraken
10
830
Fantastic passwords and where to find them - at NoRuKo
philnash
35
2.4k
[RailsConf 2023] Rails as a piece of cake
palkan
21
3.8k
Designing on Purpose - Digital PM Summit 2013
jponch
109
6.4k
From Idea to $5000 a Month in 5 Months
shpigford
376
45k
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]