Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
マルチモジュール懐疑派だったかつての自分に送る マルチモジュールの効能 モバイルアプリLT 会 一瀬喜弘(@mikanIchinose)
Slide 2
Slide 2 text
自己紹介 object Mikan { val name = " 一瀬喜弘" val company = "karabiner.tech" val work = Engineer.Android val hobby = listOf( " 漫画", " アニメ", " ゲーム", " 折り紙", "OSS 開発・コントリビュート", ) }
Slide 3
Slide 3 text
巷ではマルチモジュールが流行ってるっぽいけど なんであんな複雑そうな構成が流行るのか分からん
Slide 4
Slide 4 text
とかつて思っていた自分の疑問に答える形式で マルチモジュール構成の利点を解説
Slide 5
Slide 5 text
Q1 モジュールに分けて何が嬉しいの? Q2 モジュールを 分けると プロダクションコード以外の ファイルが 増えて、 管理コストが 増すのでは? Q3 開発スピードが落ちそう Q4 モジュールを上手に分けられる気がしない
Slide 6
Slide 6 text
Q1 モジュールに分けて何が嬉しいの?
Slide 7
Slide 7 text
1 依存の方向をビルド構成によって定義できる モノモジュール 何が何に依存しててもおかしくない
Slide 8
Slide 8 text
1 依存の方向をビルド構成によって定義できる マルチモジュール ビルド構成によって依存関係を厳密に規定できる feature-module はdata-module のコンポーネントを、domain-module はfeature- module のコンポーネントをインポートすることが不可能 // feature/build.gradle.kts implementation(project(":domain")) // domain/build.gradle.kts implementation(project(":data"))
Slide 9
Slide 9 text
2 関係ないコンポーネントが思考を遮らない モノモジュール . └── app └── src ├── data │ ├── AuthRepository.kt │ ├── AuthRepositoryImpl.kt │ ├── UserRepository.kt │ └── UserRepositoryImpl.kt ├── domain │ ├── GetUserUseCase.kt │ └── LoginUseCase.kt └── ui ├── LoginScreen.kt ├── LoginViewModel.kt ├── SplashScreen.kt └── SplashViewModel.kt
Slide 10
Slide 10 text
2 関係ないコンポーネントが思考を遮らない マルチモジュール . ├── app │ └── src │ └── MainActivity.kt ├── data-api │ └── src │ └── data │ ├── AuthRepository.kt │ └── UserRepository.kt ├── data-impl │ └── src │ └── data │ ├── AuthRepositoryImpl.kt │ └── UserRepositoryImpl.kt ├── domain │ └── src │ └── domain │ ├── GetUserUseCase.kt │ └── LoginUseCase.kt └── feature ├── login │ └── src │ └── feature │ └── login │ └── ui │ ├── LoginScreen.kt │ └── LoginViewModel.kt └── splash └── src └── feature └── splash └── ui ├── SplashScreen.kt └── SplashViewModel.kt
Slide 11
Slide 11 text
3 モジュールに分けられる構造 = 良い設計 モジュールとして切り離すことができるということは以下を達成しないといけないので自ずと良い設計になる 疎結合 共通パーツは共通なモジュール(shared, common, core) として切り出したくなる 機能間の依存がなくなるのでfeature-module 内の変更がモジュールで完結する 循環依存しない コンパイル不可能
Slide 12
Slide 12 text
モジュールを 分けると プロダクションコード以外の ファイルが 増えて、 管理コストが 増すのでは?
Slide 13
Slide 13 text
マルチモジュールを触りだしたころはそう思っていた
Slide 14
Slide 14 text
1 新しくモジュールを作るという作業は面倒 new module したときにウィザードで正しい項目を入力できているだろうか Package name とか入力するの地味にめんどくさい あとから修正したくなったときにどこまで修正したら完了なのか分からん hoge/src/main/ hoge/fuga hoge/src/main/AndroidManifest.xml hoge/build.gradle(.kts) やること自体はそこまで多くないので割とすぐ習熟する ` `
Slide 15
Slide 15 text
ソースコード以外はほとんど変化することがないので 作ってしまえばほぼ終わり
Slide 16
Slide 16 text
2 ビルド設定の共通化という難所 gradle に対する習熟度が求めれる 手段が幾通りもありどれに手を出そうか迷う 共通構成を記載したgradle ファイルを作り、各build.gralde でapply する とくにキャッシュされるわけではないのでビルドタイムには貢献しない Convention Plugin 共通処理をプラグインとして定義する
Slide 17
Slide 17 text
2 ビルド設定の共通化という難所 Convention Plugin precompiled script plugin .gradle.kts ファイルで書く 依存やバージョンをKotlin ファイルで管理 → Version Catalog が主流になったので不要かも standalone gradle plugin .kt ファイルで書く せっかく依存をVersion Catalog で管理したのに文字列で指定しなくちゃいけなくなるので微妙な気持 ち 最新のサンプル実装(nowinandroid) はこちらを使用している more information https://star-zero.medium.com/gradle のconvention-plugins-ba19a1332540 https://speakerdeck.com/jmatsu/gradle-convention-plugins
Slide 18
Slide 18 text
Q3 開発スピードが落ちそう
Slide 19
Slide 19 text
コードを書くスピードは落ちることもある
Slide 20
Slide 20 text
しかし、それとこれとはスコープの違う話
Slide 21
Slide 21 text
マルチモジュールは設計の道具 設計する = 戦略的思考 コードを書く = 戦術的思考
Slide 22
Slide 22 text
Q4 モジュールを上手に分けられる気がしない
Slide 23
Slide 23 text
アーキテクチャとか 設計系の 技術書で 勉強してください クリーンアーキテクチャ 単体テストの考え方/ 使い方 iOS アプリ設計パターン入門 ソフトウェアアーキテクチャの基礎 ー エンジニアリングに基づく体系的アプローチ ドメイン駆動設計
Slide 24
Slide 24 text
バックエンドや フロントエンドの トレンドも 参考になる バックエンド モノリス モジュラーモノリス マイクロサービス フロントエンド コンポーネント指向 Atomic Design
Slide 25
Slide 25 text
まとめ Q1 モジュールに分けることの嬉しさ → 良い設計をこころがけるようになる Q2 管理コストの増大 → あまり変化しないのでコストにならない Q3 開発スピードの低下 → 頭の使い方が違うだけなので慣れれば低下しない Q4 モジュール分割難しい → アーキテクチャとか設計の勉強して