Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Typhoon Explained

Typhoon Explained

Slides for Mobius Conference 2016.

Egor Tolstoy

June 04, 2016
Tweet

More Decks by Egor Tolstoy

Other Decks in Technology

Transcript

  1. T
    yphoon
    explained
    Egor T
    olstoy @igrekde

    View full-size slide

  2. 4
    Creating
    new project

    View full-size slide

  3. 8
    - loadBarbershops
    - cacheBarbershops
    - reloadTableData
    - loadBarbershops
    - cacheBarbershops
    - reloadTableData

    View full-size slide

  4. 9
    BarberService

    View full-size slide

  5. 10
    BarberService
    FakeBarberService

    View full-size slide

  6. 11
    BarberService
    FakeBarberService
    VC 3 VC 4
    VC 5
    VC 6

    View full-size slide

  7. 12
    @interface BarberListViewController()
    @property (nonatomic, strong) BarberServiceMain *service;
    @end

    View full-size slide

  8. 13

    BarberServiceMain
    BarberServiceFake

    View full-size slide

  9. 14
    @interface BarberListViewController()
    @property (nonatomic, strong) id service;
    @end

    View full-size slide

  10. 15

    BarberServiceMain
    Assembly
    содержат
    создает
    создает
    VC 3
    VC 4
    VC 5

    View full-size slide

  11. 16

    FakeBarberService
    Assembly
    содержат
    создает
    создает
    VC 3
    VC 4
    VC 5

    View full-size slide

  12. Assembly
    Typhoon

    View full-size slide

  13. 18
    Устройство Typhoon на трех пальцах
    Юзкейсы
    Легенды и мифы

    View full-size slide

  14. 19
    Under the
    Hood

    View full-size slide

  15. 20
    BarberViewController
    MapViewController
    BarberServiceMain
    BarberServiceFake
    Typhoon
    Component
    Factory
    componentForKey: Объект

    View full-size slide

  16. 21
    BarberServiceMain
    type: (Class)BarberServiceMain
    key: barberServiceMainDefinition

    View full-size slide

  17. 22
    BarberServiceMain
    type: (Class)BarberServiceMain
    key: barberServiceMainDefinition
    NetworkClient
    type: (Class)NetworkClient
    key: networkClientDefinition
    BarberParser
    type: (Class)BarberParser
    key: networkClientDefinition

    View full-size slide

  18. 23
    [BarberServiceMain new]
    [NetworkClient new]
    [BarberParser new]
    [BarberViewController new]
    [storyboard instantiateViewController:]

    View full-size slide

  19. 24
    Property
    Injection

    View full-size slide

  20. 25
    BarberServiceMain

    View full-size slide

  21. 26
    BarberListViewController
    type: (Class)BarberListViewController
    key: barberListViewControllerDefinition
    BarberService
    type: (Class)BarberServiceMain
    key: barberServiceMainDefinition
    BarberListAssembly

    View full-size slide

  22. 27
    @implementation BarberListAssembly
    - (BarberListViewController *)barberListViewControllerDefinition {
    return [TyphoonDefinition withClass:[BarberListViewController class]
    configuration:^(TyphoonDefinition *definition) {
    [definition injectProperty:@selector(service)
    with:[self barberService]];
    }];
    }
    - (id)barberServiceMainDefinition {
    return [TyphoonDefinition withClass:[BarberServiceMain class]];
    }
    @end

    View full-size slide

  23. 28
    Modularizing
    Assemblies

    View full-size slide

  24. 29
    BarberServiceMain
    BarberServiceMain

    View full-size slide

  25. 30
    BarberListViewController
    BarberService
    BarberListAssembly
    BarberMapViewController
    BarberService
    BarberMapAssembly
    BarberService
    ServiceAssembly

    View full-size slide

  26. 31
    @interface BarberListAssembly
    @property (nonatomic, strong) TyphoonAssembly *serviceAssembly;
    @end
    @implementation BarberListAssembly
    - (BarberListViewController *)barberListViewControllerDefinition {
    return [TyphoonDefinition withClass:[BarberListViewController class]
    configuration:^(TyphoonDefinition *definition) {
    [definition injectProperty:@selector(service)
    with:[self.serviceAssembly
    barberService]];
    }];
    }
    @end

    View full-size slide

  27. 33
    LocationServiceMain
    CLLocationManager

    View full-size slide

  28. 34
    BarberListViewController
    LocationService
    BarberListAssembly
    BarberMapViewController
    LocationService
    BarberMapAssembly
    LocationService
    ServiceAssembly
    scope: TyphoonScopeSingleton

    View full-size slide

  29. 35
    TyphoonScopeObjectGraph
    TyphoonScopePrototype
    TyphoonScopeSingleton
    TyphoonScopeLazySingleton
    TyphoonScopeWeakSingleton

    View full-size slide

  30. 36
    @implementation ServiceAssembly
    - (id)barberServiceMainDefinition {
    return [TyphoonDefinition withClass:[BarberServiceMain class]
    configuration:^(TyphoonDefinition *definition) {
    definition.scope = TyphoonScopeSingleton;
    }];
    }
    @end

    View full-size slide

  31. 37
    UI Injections

    View full-size slide

  32. 38
    BarberViewController
    MapViewController
    BarberServiceMain
    BarberServiceFake
    Typhoon
    Component
    Factory
    componentForClass:
    [BarberViewController class] [BarberViewController new]

    View full-size slide

  33. 39
    JiggleAnimator
    Calculator1
    Calculator2

    View full-size slide

  34. 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

    View full-size slide

  35. 42
    Method
    Injection

    View full-size slide

  36. 43
    MoustacheManager

    View full-size slide

  37. 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

    View full-size slide

  38. 45
    Factories,
    attributes,
    options

    View full-size slide

  39. 46
    Москва
    Питер

    View full-size slide

  40. 47

    BarberServiceMoscow
    BarberServicePiter
    ServiceAssembly
    Москва
    Питер

    View full-size slide

  41. 48

    BarberServiceMoscow
    BarberServicePiter
    ServiceAssembly
    Москва
    Питер

    View full-size slide

  42. 49

    BarberServiceMoscow
    BarberServicePiter
    ServiceAssembly

    View full-size slide

  43. 50
    @interface BarberListAssembly
    @property (nonatomic, strong) TyphoonAssembly *serviceAssembly;
    @end
    @implementation BarberListAssembly
    - (BarberListViewController *)barberListViewControllerDefinition {
    return [TyphoonDefinition withClass:[BarberListViewController class]
    configuration:^(TyphoonDefinition *definition) {
    [definition injectProperty:@selector(factory)
    with:[self.serviceAssembly]];
    }];
    }
    @end

    View full-size slide

  44. 51
    @implementation ServiceAssembly
    - (id)barberServiceForCity:(NSString *)city {
    return [TyphoonDefinition withOption:city
    matcher:^(TyphoonOptionMatcher *matcher) {
    [matcher caseEqual:@"Moscow"
    use:[self moscowBarberService]];
    [matcher caseEqual:@"Piter"
    use:[self piterBarberService]];
    }];
    }
    @end

    View full-size slide

  45. 52
    [matcher caseEqual:@"Moscow"
    use:[self moscowBarberService]];
    [matcher caseEqual:@"Piter"
    use:[self piterBarberService]];

    View full-size slide

  46. 54
    AppDelegate
    TyphoonConfig(flurryKey)
    ApplicationAssembly
    TyphoonConfig(googleKey)
    {
    "config": {
    "flurryKey": "abcdef",
    "googleKey" : "ghijkl"
    }
    }
    config.plist

    View full-size slide

  47. 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

    View full-size slide

  48. 56
    NSURL(http://mobiusconf.ru)
    MyStyle(#8732A9;17;HelveticeNeue-Regular)

    View full-size slide

  49. 57
    PostCategories(top#cyr,0,cyr,cyr|
    top#noncyr,1,noncyr,noncyr)

    View full-size slide

  50. 58
    Instance
    Postprocessor

    View full-size slide

  51. 60
    BarberListRouter

    -openScreenWithIdentifier:(NSString *)identifier

    View full-size slide

  52. 61
    RouterDecorator
    BarberListRouter
    Flurry/Google

    identifier
    identifier

    View full-size slide

  53. 62
    @implementation AnalyticsPostProcessor
    - (id)postProcessInstance:(id)instance {
    if ([instance conformsToProtocol:@protocol(Router)]) {
    return [DecoratedRouter decoratedRouterWith:instance];
    }
    return instance;
    }
    @end

    View full-size slide

  54. 63
    Integration
    T
    esting

    View full-size slide

  55. 64
    BarberServiceMain

    NetworkClientMain

    View full-size slide

  56. 65
    BarberServiceMain

    NetworkClientFake

    View full-size slide

  57. 66
    BarberListViewController
    BarberService
    BarberListAssembly
    BarberService
    ServiceAssembly
    NetworkClient
    NetworkClientMain
    NetworkAssembly

    View full-size slide

  58. 67
    BarberListViewController
    BarberService
    BarberListAssembly
    BarberService
    ServiceAssembly
    NetworkClient
    NetworkClientFake
    NetworkAssembly

    View full-size slide

  59. 68
    - (void)setUp {
    ...
    TyphoonPatcher *patcher = [[TyphoonPatcher alloc] init];
    [patcher patchDefinitionWithSelector:@selector(networkClient)
    withObject:^id{
    return [NetworkClientFake new];
    }];
    [barberListAssembly attachPostProcessor:patcher];
    }

    View full-size slide

  60. 69
    Autowiring

    View full-size slide

  61. 70
    @interface BarberListViewControllerTests
    @property (nonatomic, strong) BarberListViewController *viewController;
    @property (nonatomic, strong) id service;
    @property (nonatomic, strong) MoustacheView *view;
    @end
    - (void)setUp {
    ...
    self.viewController = [barberListAssembly viewController];
    self.service = [serviceAssembly barberService];
    self.view = [moustacheViewAssembly moustacheView];
    }

    View full-size slide

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

    View full-size slide

  63. 72
    Assembly
    Unit T
    ests

    View full-size slide

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

    View full-size slide

  65. 74
    https://github.com/rambler-ios/
    RamblerTyphoonUtils

    View full-size slide

  66. 76
    Typhoon работает со Swift

    View full-size slide

  67. 77
    Но… там же свиззлинг!

    View full-size slide

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

    View full-size slide

  69. 79
    Сильное влияние на отладку

    View full-size slide

  70. 80
    Но я же могу велосипедить...
    %

    View full-size slide

  71. 82
    Устройство Typhoon на трех пальцах
    Юзкейсы
    Легенды и мифы

    View full-size slide

  72. Egor T
    olstoy @igrekde
    Any magic, sufficiently analyzed is
    indistinguishable from technology
    [email protected]

    View full-size slide