$30 off During Our Annual Pro Sale. View Details »

大規模AndroidアプリのDIをKoinからHiltへ移行するTIPS

akkie76
February 19, 2023

 大規模AndroidアプリのDIをKoinからHiltへ移行するTIPS

「potatotips #81 iOS/Android開発Tips共有会」の登壇資料です。

https://potatotips.connpass.com/event/272353

akkie76

February 19, 2023
Tweet

More Decks by akkie76

Other Decks in Technology

Transcript

  1. potatotips #81
    ©2022 RAKUS Co., Ltd.
    大規模AndroidアプリのDIを
    KoinからHiltへ移行するTIPS
    @akkiee76
    potatotips #81 iOS/Android 開発 Tips 共有会

    View Slide

  2. potatotips #81
    Akihiko Sato / 株式会社ラクス Lead Engineer / @akkiee76
    SaaS 開発 (Backend, Frontend) / Mobile 開発 (iOS, Android)
    上流工程、コードレビュー、チームの課題改善など
    読書 / コーヒー / HHKB / あんバターフランス
    自己紹介

    View Slide

  3. potatotips #81
    会社紹介
    株式会社ラクス
    「ITサービスで企業の成長を継続的に支援します」を
    ミッションに、お客様の課題解決やビジネスの成長を
    継続的に支援するクラウドサービスを提供しています。

    View Slide

  4. potatotips #81
    今日伝えたいこと
    品質を維持しながら効率よく行う DI レガシー改善

    View Slide

  5. potatotips #81
    DI ライブラリの移行のモチベーション
    Koin AndrodX ViewModel は JCenter の廃止により
    3.0.x の開発で終了し、
     1. Maven Repository で提供されている io.insert-koin へ移行する
     2. Android 公式の Hilt に移行する
    のどちらかの選択を迫られる状況に。

    View Slide

  6. potatotips #81
    Koin の特徴
    DI が直感的に実装できるライブラリなので、
    中小規模のAndroidアプリ開発では導入がしやすい点が特徴。
    val appModule = module {
    // Interfaceを用いてDIする
    single { RepositoryImpl() }
    // ViewModelにDIする
    viewModel { MainViewModel(get()) }
    }
    class MyApplication : Application() {
    override fun onCreate() {
    super.onCreate()
    setupKoin()
    }
    private fun setupKoin() {
    startKoin {
    androidContext(this@MyApplication)
    modules(appModule)
    }
    }
    }

    View Slide

  7. potatotips #81
    Koin 実装の課題
    アプリの規模が大きくなってくると、module が肥大化し、
    可読性が低下してくる。
    val appModule = module {
    viewModel { parameters -> DetailViewModel(id = parameters.get(), get(), get()) }
    viewModel { DetailViewModel(get(), get(), get()) }
    viewModel { HogeDetailViewModel(get(), get(), get(), get(), get(), get()) }
    viewModel { FugaDetailViewModel(get(), get(), get(), get(), get(), get(), get()) }
    // 以降続く・・・
    }

    View Slide

  8. potatotips #81
    Hilt 移行のメリット
    ・ Andriod 純正ライブラリなので今後もメンテされる (おそらく)
    ・ いつかは乗り換えることになる
    ・ Jetpack ライブラリとの親和性
    ・ 乗り換えによるモチベーションアップ
    ・ 生産性の向上 (テストコード書きにくい課題の改善)
    etc

    View Slide

  9. potatotips #81
    Hilt 移行にあたって考慮するべきこと
    1. Koin と Hilt は共存できるか
    ・ 場合によっては1バージョンで乗り換えできないこともある
    2. 既存機能のデグレ
    3. Koin で実装されたテストコードをどうするか

    View Slide

  10. potatotips #81
    ここからは実際の乗り換えの手順になります。

    View Slide

  11. potatotips #81
    1. Koin と Hilt の共存調査
    まずは1バージョンで乗り換え完了できなかった場合のリスクヘッジ
    1. 依存関係を設定し、既存機能への影響度をチェック
    2. DIの引数が1つか2つのViewModelをお試し移行で影響度をチェック
    👉 機能影響なし

    View Slide

  12. potatotips #81
    2. 乗り換えの基本方針を決める
    2.1 module 実装の方針
    interface UserRepository {
    fun getUsers(): List
    }
    class UserRepositoryImpl : UserRepository {
    override fun getUsers(): List {
    }
    }
    @Module
    @InstallIn(SingletonComponent::class)
    abstract class RepositoryModule {
    @Binds
    @Singleton
    abstract fun bindUserRepository(impl: UserRepositoryImpl): UserRepository
    }

    View Slide

  13. potatotips #81
    2. 乗り換えの基本方針を決める
    2.2 Fragment, ViewModel 実装の方針
    @AndroidEntryPoint
    class MainFragment : Fragment() {
    private val viewModel: MainViewModel by viewModels()
    }
    @HiltViewModel
    class MainViewModel @Inject constructor(
    savedStateHandle: SavedStateHandle
    private val userRepository: UserRepository
    ): ViewModel() {
    ...
    }

    View Slide

  14. potatotips #81
    2. 乗り換えの基本方針を決める
    2.3 完了の定義
    1. ViewModel から KoinComponent の継承が削除されていること
    2. ViewModel の DI が by viewModels() となっていること
    3. module から対象のコードが削除されていること
    4. CI が成功していること

    View Slide

  15. potatotips #81
    3. 横展開の準備をする
    メンバー同士のレビュー待ちタスクなどで横展開していく
    1. ViewModel ごとに修正のスコープにする
    2. DI の少ない ViewModel から進めていく
    3. スプレッドシートでタスク一覧化して進捗管理する

    View Slide

  16. potatotips #81
    4. 依存関係を削除して品質を担保する
    1. Koin の依存関係を削除する
    2. 各機能のテストを実施する
    3. 機能デグレがあれば修正する

    View Slide

  17. potatotips #81
    まとめ
    1. 乗り換えの既存機能に対する影響を調査
    2. 実装方針を確立する
    3. 横展開で修正する
    4. 依存関係を削除
    5. デグレチェック
    このプロセスで効率的に乗り換え作業が進められます。

    View Slide

  18. potatotips #81
    今後の課題
    テストコードまでは修正できず、テストの依存関係はそのまま
    👉 テストフレームワークの見直しを含めて対応予定

    View Slide

  19. potatotips #81
    ご静聴ありがとうございました

    View Slide