Кінжал 2 @Binds vs @Provides

Пачынаючы з кінжала 2.12 (прабачце, я яго ведаю даволі даўно ... але ўсё ж варта разумець гэта), новая функцыя пад назвай @Binds дададзеная ў кінжалы. Пра гэта ўжо ёсць некалькі блогаў. Аднак чытанне іх усё яшчэ прымушае задумацца, якую перавагу ён мае для старых верных @Provides, якія ёсць у нашых модулях.

Паколькі мая мэта складаецца ў тым, каб зрабіць усё максімальна зразумелым, таму я пішу гэта пасля таго, як правяду ўласнае расследаванне, такім чынам, каб ясна растлумачыў мае пытанні.

Што адрозніваецца ў сэнсе кадавання

@Provides

@Module
клас MyModule {
    @Provides
    fun getInjectClass (injectObject: InjectClass): InjectInterface {
        вярнуць injectObject
    }
}
канструктар класа InjectClass @Inject (): InjectInterface
інтэрфейс InjectInterface

@Binds

@Module
абстрактны клас MyModule {
    @Binds
    абстрактнае задавальненне getInjectClass (injectObject: InjectClass):
        InjectInterface
}
канструктар класа InjectClass @Inject (): InjectInterface
інтэрфейс InjectInterface

З усяго вышэйсказанага няма відавочнай відавочнай перавагі @Binds над @Provides. Адзін ператварыўся ў абстрактны клас і функцыю, а другі - у канкрэтны. Гэта не зніжае шматслойнасці (альбо котла).

У чым жа перавага @Binds?

Каб даведацца пра гэта, давайце паглядзім некаторыя гісторыі

Гістарычна ...

На вельмі-вельмі-вельмі ранняй стадыі кінжала няма такога паняцця, як @Module. @Module на самай справе не патрэбны для працы Dagger 2 (праверце самы кароткі ў свеце код кінжала 2).

Аднак людзі скардзіліся і хацелі аб'яднаць утрыманцаў разам. Такім чынам, распрацоўшчык Dagger 2 паддаўся і стварыў гэты вядомы вядомы функцыю выкліку @Module, які мае перавагі так, як гэтага хочуць многія.

Тым не менш, існаванне @Module з @Provides сапраўды ўносіць некаторыя выдаткі ў згенераваны код. У гэтым дапамогу пазначылі @Binds.

Дакажыце мне ...

Выкарыстоўваючы прыведзены вышэй код (разам з @Component, які не паказаны ў фрагменце кода вышэй) ... давайце паглядзім на розныя

Дадатковыя модульныя фабрычныя класы

Ніжэй прыводзяцца сфармаваныя класы.

Звярніце ўвагу, што @Provides стварае клас MyModule_GetInjectClassFactory, які не існуе ў @Binds

Як выглядае клас? Нічога сабе, зусім няшмат кодаў ..

Акрамя таго, гэта толькі для аднаго InjectClass. Але калі ў нашым модулі іх больш за 1, кожны з іх будзе сам ствараць заводскі клас

@Provides
fun getInjectClass (injectObject: InjectClass): InjectInterface {
    вярнуць injectObject
}
@Provides
fun getInjectClass2 (injectObject2: InjectClass2): InjectInterface2 {
    вярнуцца injectObject2
}
@Provides
fun getInjectClass3 (injectObject3: InjectClass3): InjectInterface3 {
    вярнуцца injectObject3
}

Уявіце, як гэта дадасць наш DexCount і памер прыкладання !!

Дадатковы пласт абгорткі модуля

За выключэннем дадатковага класа Модульны фактар, калі мы вывучым створаны наш клас DaggerMyComponent, мы ўбачылі б памер кода розны.

Ружовы колер - гэта толькі ў @Provides, а зялёны - у @Binds

@Provides генеруе 52 радкі кодаў, а @Binds генеруе толькі 29 радкоў кода (~ 40% зніжэнне !!).

Калі вы прасачыце код, вы ўбачыце, як паказана ніжэй.

Паглядзіце, наколькі лаканічны @Binds у стварэнні InjectObject?

Карацей кажучы, не толькі @Binds памяншае колькасць радкоў, але і памяншае стварэнне аб'екта, а таксама аперацыйны паток.

Такім чынам, давайце зменім усё на @Binds?

На жаль, @Binds працуе толькі на аснове прыведзеных ніжэй правілаў

Метады @Binds павінны мець толькі адзін параметр, тып якога можна аднесці да тыпу вяртання

Такім чынам, толькі адзін параметр, і тып вяртання, як правіла, з'яўляецца інтэрфейсам дадзенага аб'екта параметра.

Сказаўшы гэта, іншыя парады разгледзяць магчымасць выкарыстання статычнай функцыі для @Provides, якая таксама дапаможа паменшыць некаторыя згенераваныя коды.

Праверце частку 1 раздзела ніжэй блога, каб атрымаць больш падрабязную інфармацыю (прачытаўшы вышэй, вы можаце атрымаць больш дакладнае разуменне блога ніжэй)

Я спадзяюся, што гэты пост вам карысны. Тут вы можаце пачытаць і іншыя мае цікавыя тэмы.

Сачыце за мной, у Twitter ці Facebook, каб атрымаць невялікія парады і даведацца пра Android, Kotlin і іншыя адпаведныя тэмы. ~ Элі ~