はじめに
DELISH KITCHENでクライアントグループのマネージャーをやっている今井です。 クライアントチーム初のブログということで、DELISH KITCHENの Androidアプリの今の構成の話と、 アプリを作って4年が経とうとしてる中での変遷を紹介していきます。
なお、このブログは全体の構成の雰囲気を掴んでもらうことを目的にしておりますので、 細かい設計の話や採用技術の細かい特徴の紹介は割愛させていただきます。 それらはまた別の機会に紹介できればと思います。
現在の構成
ここでは現在のプロジェクトの構成とアプリで採用しているアーキテクチャの紹介をしていきます。
プロジェクトの構成
DELISH KITCHENのAndroidアプリではMultiModuleを採用しており、
大きく app
core
features
の3種類のModuleに分かれています。
app いわゆるメインモジュールです。feature間をつなぐためのRouterの実装や、 ライブラリの初期化等を行っております。 歴史上の理由でここにもまだまだfeature要素が残ってしまっていますが、 徐々にfeatureモジュールに切り出しています。
core 各モジュールの共通で使う拡張関数やユーティリティクラスなどを入れています。 モジュール間の遷移に使ってるRouter等もここでInterfaceを定義しており、 実態はappモジュールで実装、DIで各モジュールに配布しています。
features 実際にfeaturesというモジュールがあるわけではなく、 機能ごとにfeatureモジュールとして分割しています。 各featureモジュールではcore以外のmoduleのimportを禁止しており、 強制的に参照不可にすることで依存をなるべく減らしています。
アーキテクチャ
アーキテクチャとしてはMVVM+レイヤードアーキテクチャを採用しています。
図の通りですが、Android Architecture Component(以下、AAC)を全面採用し、 MVVM+レイヤードアーキテクチャを構成しています。 ViewModelはそのままAACのViewModelを採用しており、 ViewModelからViewへのデータの公開はLiveData、 ViewからActionの受け付けはシンプルにメソッドコールにしています。 通信部分はKotlin Coroutineで繋いでいます。
この構成にいたるまでいろいろ変遷してきているので、 その一部を次で紹介します。
変遷
この4年間でKotlinがGoogleに正式にサポートされたり、AACやJetpackが登場したり Android界隈で大きくデファクトが変わってきました。 DELISH KITCHENのAndroidアプリではそれに対して比較的柔軟に採用技術を変更してきました。 その中で大きく変更があった3点を紹介します。
1. MonoModuleからMultiModuleへ
コード量が増えてきてビルド時間が長くなってきたので検討し始めました。 副産物的な感じでしたが、参照をあえて出来なくすることで依存関係を意識せざるを得ない状況になり、チーム全体の依存に対する意識が向上しました。また、その事に頭を使わなくて良くなったのでとても良かったです。 分割し始めた当初はInstant AppやDynamic Feature Moduleも検討していました。
2. Android Architecture Componentの採用とRxの置き換え
リリースから1年くらい経つと、機能が乗ってしまったいわゆるSuperActivity/Fragmentが出現し始めたので、 MVVMやFluxの導入を考えていたところAACが発表されたため即採用しました。 またAPI通信まわりは各レイヤーの繋ぎにとどまっていたRxをKotlinCoroutineとLiveDataに置き換えることで、 AACの恩恵をフルで受けれるような構成に変更しました。
3. Viewへのアクセス周りの変遷
ここが一番紆余曲折あったところです。 ざっくりと KotterKnife → Kotlin Android Extension → Databinding → ViewBinding と変更してきました。 初期はJavaのButterKnifeの流れでKotterKnifeを採用してたものの、 型安全じゃないとかFragmentで使えないなどの理由から、Kotlin Android Extensionに移行しました。 その後すぐにnullableになってしまうのが辛くなったのと、xml上で値を設定できる便利さからDataBindingを採用しました。 DataBinding自体は全然問題なかったんですが、あまり双方向Bindingを生かす場面がなかったのと、 ロジックがxmlにも一部分散することでコードレビューが大変になったので、現在はViewBindingを採用しています。 加えてViewBindingはDataBindingビルドが速かったり、型安全だったりと、しばらくはViewBindingで落ち着きそうです。
(おまけ) Dagger → Koin
人類にはDaggerは早かった(笑) っていうのもありますが、Daggerの機能をそんなに活かしきれていなかったのと、 誰でも比較的簡単にライブラリの挙動が理解できるようにKoinに変更しました。 設計自体に影響が大きくあった訳ではないですが、コードの変更量が膨大で、 変更作業が一番辛かったのでおまけとして紹介させてください(笑)。 そんな中、今年出たDaggerHiltへの変更を検討中だったりもします😇。
まとめ
DELISH KITCHENのAndroidのアプリに関して少しでも知っていただけたら幸いです。 今回ご紹介した設計がベストだとは考えていませんし、まだまだ発展途上です。 アプリの規模にかかわらず、良いものであれば積極採用することはぶらさず、 開発してて楽しい環境を作りながら、より良いアプリをより早く提供できるように努めていければと思ってます。