Android アプリのモジュール化のガイド

複数の Gradle モジュールがあるプロジェクトは、マルチモジュール プロジェクトと呼ばれます。このガイドでは、マルチモジュール Android アプリを開発するためのおすすめの方法と推奨パターンを紹介します。

拡大するコードベースの問題

コードベースが拡大し続けると、スケーラビリティ、読みやすさ、全体的なコード品質が時間の経過とともに低下しがちです。これは、メンテナンス担当者が保守の容易な構造を積極的に採用せず、コードベースのサイズが増加した結果です。モジュール化は、保守性を向上させ、これらの問題を回避するようにコードベースを構造化する手法です。

モジュール化とは

モジュール化とは、コードベースの結びつきを弱め、自己完結型の部分に編成することを意味します。各部分がモジュールになり、それぞれのモジュールが独立して、役割も明確になります。問題を小さく解決しやすいサブ問題に分割することで、大規模なシステムの設計と維持に関する複雑さが軽減されます。

図 1: サンプルのマルチモジュール コードベースの依存関係グラフ

モジュール化の利点

モジュール化の利点は数多くありますが、いずれもコードベースの保守性と全体的な品質の向上につながるものです。次の表は、主な利点をまとめたものです。

利点 概要
再利用性 モジュール化により、コードを共有し、同じ基盤から複数のアプリを作成できるようになります。モジュールにより、ブロックが効果的に作成されます。アプリは機能を組み合わせたものとなり、各機能は個別のモジュールとして整理されます。特定のモジュールが提供する機能は、アプリによって有効になる場合とならない場合があります。たとえば、:feature:news を完全版のフレーバーや Wear アプリの一部にすることはできますが、デモ版のフレーバーの一部にすることはできません。
厳密な表示設定管理 モジュールを使用すると、コードベースの他の部分に公開する範囲を簡単に制御できます。公開インターフェース以外はすべて internal または private としてマークすると、モジュールの外部での使用を防ぐことができます。
カスタマイズ可能な配信 Play Feature Delivery は、App Bundle の高度な機能を使用することで、アプリの特定の機能を条件付きまたはオンデマンドで配信できます。

上記の利点は、モジュール化されたコードベースでのみ得られます。他の手法でも次のメリットを得られる場合がありますが、モジュール化を使用したほうがより得られやすくなります

利点 まとめ
拡張性 密結合されたコードベースでは、1 回の変更で、コードの一見関係のない部分にも連鎖的に変更が行われる場合があります。適切にモジュール化されたプロジェクトでは、関心の分離の原則が適用されるため、結合が制限されます。これにより、自律性が高まり、コントリビューターの利便性が高まります。
オーナーシップ 自律性を高めることだけでなく、アカウンタビリティの強化のためにモジュールを使用することもできます。モジュールでは、コードの保守、バグの修正、テストの追加、変更のレビューを担当する専任のオーナーを指定することができます。
カプセル化 カプセル化とは、コードの各部分が他の部分について最小限の知識しか持たないことを意味します。分離されたコードは読みやすく、理解しやすくなります。
テストの容易性 テストの容易性とは、コードがどれほど簡単にテストできるかを意味します。テストしやすいコードとは、コンポーネントを単独容易にテストできるコードです。
ビルド時間 増分ビルド、ビルド キャッシュ、並列ビルドなど、Gradle の一部の機能ではモジュール性を利用してビルドのパフォーマンスを改善できます。

主な注意点

コードベースの粒度とは、コードベースがどの程度モジュールで構成されるかを指します。粒度が高いコードベースとは、モジュールの数が多く、またそれぞれのモジュールが小さいことを指します。モジュール化されたコードベースを設計する場合は、粒度を決定する必要があります。その場合は、コードベースのサイズとその相対的な複雑さを考慮します。粒度が高すぎるとオーバーヘッドが負担になり、粒度が低すぎるとモジュール化の利点が少なくなります。

よくある間違いとして、次のようなものがあります。

  • 粒度が高すぎる: どのモジュールにもある程度のオーバーヘッドがあり、ビルドの複雑さとボイラープレート コードの増加という形で表れます。ビルド構成が複雑になると、モジュール間で構成の一貫性を保つことが難しくなります。ボイラープレート コードが多すぎると、コードベースの保守が難しくなります。オーバーヘッドが原因でスケーラビリティの改善がうまくいかない場合は、いくつかのモジュールの統合を検討してください。
  • 粒度が低すぎる: 逆に、モジュールが大きくなりすぎると、さらに別の問題が生じ、モジュール性による利点が失われる可能性があります。たとえば、小規模のプロジェクトでは、データレイヤーを 1 つのモジュール内に配置しても問題ありません。しかし、規模が大きくなると、リポジトリとデータソースをスタンドアロン モジュールに分けることが必要となる場合があります。
  • 複雑すぎる: プロジェクトをモジュール化しても意味がない場合もあります。重要な要素はコードベースのサイズです。プロジェクトが一定の規模に達しないと考えられる場合、スケーラビリティとビルド時間の改善は見込めません。

モジュール化した方がよいかどうかを判断する基準

再利用性、厳密な公開設定管理、Play Feature Delivery の使用が必要となる場合は、モジュール化が必要です。これらは必要ではないものの、スケーラビリティ、オーナーシップ、カプセル化、ビルド時間の改善を求めている場合は、モジュール化を検討してください。

サンプル