🪐

Luup Android Repositoryでモジュール分割を進めてみた。

2023/12/12に公開

こんにちは、Luupで業務委託をしているsyam(@arus4869)です。
今日は、Androidアプリの開発における重要な側面である「モジュール分割」について、Luupでモジュール分割を進めた経験を元にシェアしたいと思います。
Android開発に携わる方々へ、この記事が実際の開発で役立つ洞察を提供できれば幸いです。

はじめに

私が業務委託としてLuupに参画する以前から、Android Repository内では、アーキテクチャを改善するための話し合いが進められていました。
そこで、アーキテクチャの改善の1つの手段として、appモジュールに集中していたusecaseクラス群やServiceクラス群を、より効果的に管理し再利用可能にするため、モジュール分割を提案し進めることになりました。

モジュール分割のプロセス

モジュール分割において最初に取り組んだのは、方針の策定でした。
プロジェクトの既存のアーキテクチャを分析し、どのように分割すれば最も効果的かを検討しました。
検討の過程では、Notionを活用して、分割の方針や責務を明確にするためのドキュメントを作成しました。

分割の具体的な戦略としては、いきなりFeatureモジュール化は行わず、data層とusecase層に焦点を当てモジュール分割を進めることにしました。
data層では、データの取得や保存、変換処理を担当するrepositoryとrepository-implモジュールを設計しました。
ここでは、DBのコストパフォーマンスも考慮しながら、データの加工やフィルタリングの処理を担当するよう設計しています。
一方、usecase層では、アプリケーションの操作や情報取得のロジックを担当するクラス群を配置することにしました。
これらは複数のViewModelで再利用されることを目指して設計しました。

このプロセスでは、Slackでのディスカッションを通じて、チームメンバーと意見交換を行い、共通の理解を築くことが重要でした。
最終的にこの意見交換を行いNotionで作成した方針がアップデートされていきました。

data層について

data層のモジュール分割のステップについて紹介します。
まず、data層をdata:repositorydata:repository-implに分割しました。
主な理由は、増分ビルドの効率化と一部の依存解決を目的としたものでした。
分割のおかげで、usecase層はデータ取得の方法について詳細を知る必要がなくなるメリットを得ることができました。
結果、usecase層はrepositoryにのみ依存し、データ取得のインターフェースに集中することが可能になりました。

またdata層をモジュール分割するプロセスの一環として、:core:entity:core:androidという新たなモジュールも追加しました。
これはappモジュールで使われていたクラスが、data層など他のモジュールでの共通参照を得る必要があったためです。

:core:entityモジュールは、アプリケーションの中核をなすビジネスロジックやデータ構造を表すドメインモデルを定義し、appモジュールを含む他のモジュール間で共有されます。
一方、:core:androidモジュールは、アプリケーション全体で共有される基本的なコンポーネントやユーティリティクラスを提供し、ロギングや依存関係注入の設定などを含んでいます。

これらのモジュールは、アプリケーションの構造をより明確にし、各機能間の依存関係を適切に管理するために重要でした。
結果として、他モジュールでも効率的な作業が可能になりました。

usecase層について

usecase層については、usecaseモジュールを作成し、すでにあるusecaseクラスを移動させる単純なものになりました。
この際にdata層で共通モジュールを作成したおかげで、元々appモジュール内にあったusecaseクラスの関連ファイルを:core:entity:core:androidに移動させるだけで、
usecaseモジュールで参照を持つことができたので、とても効率的に作業できました。
下記画像は、最終的に出来上がったモジュール分割のイメージ図になります。
モジュール分割のイメージ図

おわりに

本取り組みにおいて学んだ最大の教訓は、チーム内での共有理解の構築の重要性です。
:core:entity:core:androidについては、最初の方針から漏れていたので、PR内でディスカッションをすることになりました。
data層のモジュール分割のPR内で対応していたこともあり、結果的に1つのPRがかなり膨らんでしまいました。
方針を決める際に関連ファイルについても事前に意識しておくとPRを分けたり、ディスカッション以外の単純なモジュール分割の作業に集中できたと思うので、このあたりは反省しています。

アーキテクチャはアプリの基盤となるもので、その設計が全ての開発プロセスに影響を与えます。
モジュール分割はアーキテクチャ全体に影響する関心ごとの高いトピックになるので、事前にチーム内のコミュニケーションと共有理解の構築を得ることが、重要であることが改めて認識しました。
次のステップとして、今回の取り組みで得た知見を活かし、チームの生産性とサービスの拡張性を高めるためにFeatureModule化を進めていきたいと思います。

参考文献

Luup Developers Blog

Discussion