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
260
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Typhoon Explained
Slides for Mobius Conference 2016.
Egor Tolstoy
June 04, 2016
More Decks by Egor Tolstoy
See All by Egor Tolstoy
Как подсидеть тимлида
etolstoy
0
440
OKR без хайпа
etolstoy
1
370
OKR: инструкция по применению
etolstoy
0
640
Avito Mobile: State of the Union
etolstoy
0
190
Developer Experience: The Art of Building Spaceships
etolstoy
1
700
Выступайте
etolstoy
0
230
Улучшая performance review
etolstoy
0
1.6k
May the Code Review be with you [English]
etolstoy
1
280
May the Code Review be with you [Russian]
etolstoy
1
240
Other Decks in Technology
See All in Technology
ブロックチェーン / Blockchain
ks91
PRO
0
120
中期計画、2回作ってみた ~業務委託と正社員、両方の視点から~
demaecan
1
560
非エンジニアがClaudeと挑んだ「1ヶ月間プロダクト30本ノック」
askokc
0
160
「コーディング」しない人のための Claude Code 入門 ChatGPT の次の一歩 — 業務に組み込む 育成・共有・自動化
rfdnxbro
2
1.3k
AI-DLCを活用した高品質・安全なAI駆動開発実践 / AI Driven Development with AI-DLC
yoshidashingo
0
160
Claude Code×Terraform IaC テンプレート駆動開発
itouhi
1
460
関西に縁あるMicrosoft MVPsが語るCopilotの未来
kasada
0
1.2k
Rancherの紹介&Update情報(RancherJP Online Meetup #09)
yoshiyuki_kono
0
140
AWSシリコン最前線 〜AI時代のチップ選択を読み解く〜
htokoyo
2
310
Agentic ERPをどう設計するか ー 受発注エージェントを動かす、現場の知見と設計思想ー
recerqainc
1
2.1k
スキルと MCP ツール、責務をどう分けるか? AI が迷わないインターフェース設計の戦略
cdataj
1
770
生成 AI × MCP で切り拓く次世代 SRE!自律型運用への挑戦と開発者体験の進化
_awache
0
180
Featured
See All Featured
How to make the Groovebox
asonas
2
2.2k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
160
Docker and Python
trallard
47
3.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
First, design no harm
axbom
PRO
2
1.2k
Paper Plane (Part 1)
katiecoart
PRO
0
8.8k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
170
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.3k
The Illustrated Guide to Node.js - THAT Conference 2024
reverentgeek
1
380
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
54k
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]