Slide 1

Slide 1 text

クックパッドアプリに おける DI の歴史 @ksfee684

Slide 2

Slide 2 text

自己紹介 ● 加藤 恭平(@ksfee684) ● モバイル基盤部所属 ● Android アプリプロジェクトの開発効率化、基盤技術開発

Slide 3

Slide 3 text

● クックパッドアプリの DI フレームワークの変遷 ● クックパッドアプリにおける各 DI フレームワークの解説 ○ 選定理由 ○ 利用方針 ■ フレームワーク移行に伴った変更 アジェンダ

Slide 4

Slide 4 text

今日はなさないこと ● DI フレームワーク利用方法の説明 ● DI フレームワークの必要性 ● DI フレームワークごとの比較 ○ 選定理由で少し出てきますが、全体通して比較はありません

Slide 5

Slide 5 text

DI フレームワークの変遷 RoboGuice (? ~ 2018) Toothpick (2018 ~ 2019) KOIN (2019 ~ 2020) Dagger (2020 ~) 移行を担当 見直し 見直し

Slide 6

Slide 6 text

RoboGuice (?~2018)

Slide 7

Slide 7 text

RoboGuice ● https://github.com/roboguice/roboguice ○ Google Guice をAndroid に転用したもの ● リフレクションベースの DI フレームワーク ● 恐らくクックパッドアプリに入った最初の DI フレームワーク

Slide 8

Slide 8 text

利用方針 ● 主にインスタンス生成を省略するために利用 ● Activity や Fragment から値を注入 ● DI フレームワークの利用ルールはなく、開発者の裁量にあわせて利用 ○ 複雑に絡み合うオブジェクトの依存関係

Slide 9

Slide 9 text

RoboGuice の課題点 ● 当初はリリースされるはずであった RoboGuice4 に乗り換える予定だった ● 雰囲気が怪しくなり乗り換えを考え始める

Slide 10

Slide 10 text

Toothpick (2018~2019)

Slide 11

Slide 11 text

Toothpick ● https://github.com/stephanenicolas/toothpick ● アノテーションプロセッサを利用した DI フレームワーク ● 依存グラフを持つ Scope が木構造のような親子関係を持つ ○ ApplicationScope, ActivityScope

Slide 12

Slide 12 text

Toothpick の選定理由 ● 移行にあたって利用方針の見直しは行われないことに ● 乗り換え先として Dagger, Toothpick が上がる ○ 元々 RoboGuice を上手く活用できておらず、 Dagger の複雑さと学習コストに対して得られるも のが少ない ○ 縦横無尽な利用方法を整備する上では Dagger の方が強制力がある ○ Toothpick の方が移行が容易 ● 構造がシンプルで移行が比較的容易な Toothpick を選定

Slide 13

Slide 13 text

Toothpick の課題点 ● アノテーションプロセッサを利用するようになりビルド時間が増加 ● 移行当初 Toothpick がまだ発展途上で不安な箇所がいくつかあった ○ アノテーションプロセッサによるコード生成

Slide 14

Slide 14 text

KOIN (2019~2020)

Slide 15

Slide 15 text

KOIN ● https://github.com/InsertKoinIO/koin ● Kotlin ベースのジェネリクスと Delegated Properties を利用した DI フレームワーク ● 依存グラフは実行時に Map 上で構築される ○ Lazy Properties として Map に対してオブジェクトをリクエストする

Slide 16

Slide 16 text

KOIN の選定理由 ● アノテーションプロセッサを利用しない DI フレームワークを探し始める ○ 移行の容易さ、DI フレームワークの利用の見直しも同時に行う ● KOIN, Kodein, Dagger が候補に上がる ● 導入のしやすさが決め手に ○ 巨大な Map 構造を築くだけで、初学者にも理解しやすい ○ パフォーマンス面も申し分なし ○ アノテーションプロセッサによるコンパイル時間の増加を回避できる ○ Kotlin コードが拡充しつつあった

Slide 17

Slide 17 text

移行に合わせた利用方針の見直し1 ● Toothpick 移行時に先送りになっていた利用方針の見直し ○ 複雑に絡み合っていたオブジェクトの依存関係を整理 ○ VIPER + レイヤードアーキテクチャ上で DI フレームワークを活用する ■ マルチモジュールも意識した構成に

Slide 18

Slide 18 text

オブジェクトの依存関係の整理 ● 単純にオブジェクト生成を省略していたものは DI フレームワークの利用をやめる ○ DI フレームワークを利用するオブジェクトのルールを設定 ● 縦横無尽に注入される Context をやめる ○ ApplicationContext? ActivityContext? ● xxHolder の削除 ○ シングルトン制約を DI フレームワークが担うように

Slide 19

Slide 19 text

VIPER + レイヤードアーキテクチャにおける利用 ● VIPER + レイヤードアーキテクチャの上で扱うオブジェクトの生成を DI フレームワークを介して行うよ うに ● オブジェクト間はすべてインタフェースを介して会話 ○ オブジェクト生成をすべて任せることで、実体を知らずに済むように ○ テスト実行時にオブジェクトのすり替えが可能に

Slide 20

Slide 20 text

RecipeDataSource VIPER + レイヤードアーキテクチャにおける利用 ServerRecipeDataSource RecipeContract.View RecipeActivity RecipeContract.Interactor RecipeInteractor RecipeContract.Presenter RecipePresenter RecipeContract.Routing RecipeRouting VIPER レイヤード アーキテクチャ

Slide 21

Slide 21 text

RecipeDataSource VIPER + レイヤードアーキテクチャにおける利用 Mock RecipeContract.View RecipeActivity RecipeContract.Interactor RecipeInteractor RecipeContract.Presenter RecipePresenter RecipeContract.Routing Mock VIPER レイヤード アーキテクチャ

Slide 22

Slide 22 text

KOIN の課題点 ● 依存グラフが不十分でもコンパイル時に気づくことができない ○ リリース後に Crashlytics で実行時エラーに気づく ○ 開発者がアプリ実行まで問題に気づけず生産性が落ちる ● クックパッドアプリと Scope の相性が悪い ○ ライフサイクルとのひも付きが不十分

Slide 23

Slide 23 text

Dagger (2020~)

Slide 24

Slide 24 text

Dagger ● https://github.com/google/dagger ● アノテーションプロセッサを利用した DI フレームワーク ● Google によってメンテナンスが行われている Android 公式フレームワーク

Slide 25

Slide 25 text

Dagger 選定理由 ● 課題を解決するために残された最後の手段 ○ コンパイル時の依存グラフチェック、依存注入タイミングの改善 ● KOIN 導入段階で利用方針を整理したため Dagger の機能を活用できるようになった ● Hilt の導入 ○ 移行開始当初存在を知らなかった

Slide 26

Slide 26 text

移行に合わせた利用方針の見直し2 ● KOIN で自由に依存注入していた箇所をなくす ○ エントリーポイントを Activity, Fragment, Service, BroadcastReceiver に限定 ○ グローバルな値として参照していた箇所を排除

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

そして次の時代へ…

Slide 29

Slide 29 text

Dagger Hilt ● 実は移行を進めているタイミングで知らなかった … ● 更にアノテーションプロセッサによるコードジェネレーションが強まる ○ アノテーションだけつければ良くなる時代へ ○ 初学者の学習コスト軽減 ● クックパッドアプリを題材に移行を試みたブログを書いたのでよければ ○ https://ksfee.hatenablog.jp/entry/2020/06/17/033304