Androidアーキテクチャことはじめ ― 選定する意味と、MVP、Clean Architecture、MVVM、Fluxの特徴を理解する

Androidアプリの開発において悩ましいアーキテクチャの選定。本記事では選定する意味を改めて整理し、 MVP・Clean Architecture・MVVM・Fluxといった最新の実例を紹介します。

Androidアーキテクチャことはじめ ― 選定する意味と、MVP、Clean Architecture、MVVM、Fluxの特徴を理解する

はじめまして。Androidエンジニアの藤原聖(ふじわら・さとる/@satorufujiwaraです。
現在は株式会社サイバーエージェントで、エンジニアリングマネージャーを兼任しています。2017年で35歳になり、定年を迎えました(プログラマの定年については「体型を支える技術」などを参照)

Androidアプリ開発には2010年から携わっていますが、今現在の関心事は何といっても公式開発言語に採用されたKotlin。そしてもう一つが、Androidのアーキテクチャ(設計)です。私もこれまで次のような記事を公開してきました。

1RxJava + Flux (+ Kotlin)によるAndroidアプリ設計2
3Kotlin + Architecture Component + Dagger2によるAndroidアプリ設計4

Android開発において、アーキテクチャを考えることはとても重要です。上記のエントリーでも述べたように、アーキテクチャに絶対の正解はなく、アプリケーションの規模やチームによってさまざまな形が考えられます。

また、Androidのアーキテクチャについては国内海外を問わず、これまでさまざまな議論が行われてきましたが、2016年にアーキテクチャのサンプルである「Android Architecture Blueprints」がGoogleによって公開され、さらにGoogle I/O 2017では「Android Architecture Components」が発表されました。

これによって、Androidにおけるアーキテクチャの議論はいったん収束の時期を迎えているように思います。

本記事では、Androidにおいてアーキテクチャを選定する意味を改めて整理し、現状のAndroidのアーキテクチャの実例を紹介します。これからAndroidのアーキテクチャを考える方々の参考になれば幸いです。

アーキテクチャにおけるデザインパターン

Androidも含めたモバイルアプリケーションにおいてアーキテクチャといえば、MVC(Model View Controller)やMVP(Model View Presenter)といったものが思い浮かぶかと思います。これらは、言葉を省略せずに言うなら「アーキテクチャにおけるデザインパターン」のことです(例えば、MVCはユーザーインタフェースを持つアプリケーションソフトウェアを実装するデザインパターン)

デザインパターンというとGoFによるものが有名ですが、Wikipediaの「デザインパターン」の項目では次のように説明されています。

デザインパターン(略)とは、過去のソフトウェア設計者が発見し編み出した設計ノウハウを蓄積し、名前をつけ、再利用しやすいように特定の規約に従ってカタログ化したものである。

すなわち、アーキテクチャは「名前のついた、再利用するための設計ノウハウ」のことだと言えます。本記事では、この「設計ノウハウ」のことをアーキテクチャと呼ぶことにします。

アーキテクチャはなぜ必要か?

アーキテクチャはデザインパターンのことだと書きましたが、再びWikipediaの「デザインパターン」でGoFに関する記述を参照すると、こう書かれています。

コンピュータのプログラミングで、素人と達人の間では驚くほどの生産性の差があり、その差はかなりの部分が経験の違いからきている。達人は、さまざまな難局を、何度も何度も耐え忍んで乗り切ってきている。そのような達人たちが同じ問題に取り組んだ場合、典型的にはみな同じパターンの解決策に辿り着く。これがデザインパターンである(GoF)

すなわち、デザインパターンとは、達人が編み出した典型的な問題解決の手段ということができます。

冒頭で書いたように、アーキテクチャに絶対の正解はなく、アプリケーションの規模やチームによってさまざまな型(デザインパターン)が考えられます。なぜならアプリケーションの規模やチームによって解決すべき問題が異なるからです。

問題を解決するためにアーキテクチャのデザインパターンが必要であり、問題の内容に応じてデザインパターンは異なります。したがって、アーキテクチャを選定する際には「解決したい問題が何か?」を考える必要があります。

アーキテクチャによって解決すべき問題とは?

アーキテクチャを用いて解決するべき問題とは、どのような問題なのでしょうか?

アプリケーションの規模やチームによって抱える問題は異なるものの、Androidアプリケーションを作成する上で、多くの人が似たような問題に直面すると思います。まずはそうした一般的な問題について考えてみましょう。

MVCやClean Architectureなど、Androidで用いられているアーキテクチャの多くは、もともとWebアプリケーションで用いられていました。したがって、Androidで解決すべき問題にも、Webアプリケーションと同一のものが存在します。

ここでは、Webアプリケーションでも存在する問題と、Android固有の問題とに分けて考えることにします。

余談になりますが、名前をつけて再利用することがアーキテクチャなのだとしたら、AndroidにおいてはWebアプリケーションで用いられている名前とは少し別のものをつけてサンプルなどを公開した方がよいのかもしれません。例えばMVCアーキテクチャは、Androidにおいては実装者によってそれぞれ別の仕上がりになるように思います。Clean ArchitectureはAndroid-CleanArchitectureとしてサンプルが公開されているので、同じ実装が想像できる良い例です。

Webアプリケーションでも存在する問題

まずは、Webアプリケーションにおける問題のうち、Androidにも持ち込めそうなものについて考えます。

関心の分離

最初の問題は、ビジネスロジックの関心事と、技術的な関心事が適切に分離されないことです。

特に、Androidのようなクライアントアプリケーションにおいては、UI(ユーザインタフェース)の表示ロジックと、その他のビジネスロジックが適切に分離されていなければ、クラスの肥大化などの問題が発生します。

テスティング

AndroidアプリケーションはJava(もしくはKotlin)で記述されていますが、Androidフレームワークに依存している部分は、JUnitなどによるJavaのユニットテストを実施することができません。

また、表示されているUIが正しいかどうかのテストでは、状態管理処理とUI表示の処理とを適切に分離しなければ、 その表示が正しく行われているかのテストを書くことは難しくなります。

複数人による開発

複数人で開発すると、どうしても個人による癖などが出やすくなります。「どの処理をどのクラスに書くべきか」といったことが、コードレビューの際に議論になることも多いでしょう。

また、GitHubなどでソース管理をしている際に、同じクラスを同時に編集したりしてコンフリクトが発生し、開発速度が低下するなどの問題もあるでしょう。

Android固有の問題

前節では一般的なWebアプリケーションでも起こりうる問題を検討しましたが、ここではAndroidフレームワークに起因する問題について考えてみます。

Activityの肥大化

Androidにおいては、Activity(Androidアプリ画面)が多くの役割を担うことができます。MVCアーキテクチャをAndroidに適用すれば、ViewとController両方の役割をこのActivityが担っていると考えることもできます。

小規模なアプリケーションならばActivityにそれらの処理を記述すればよいのですが、アプリケーションが大規模になればなるほどActivityクラスへの記述量が増え、いわゆるActivityの肥大化という問題が発生します。

肥大化したActivityは、開発者がソースコードから処理を追うのが難しく、開発速度の低下や、バグの発生要因にもなり得ます。

Activityのライフライクル

Activityは独自のライフサイクルを持っており、画面を回転したりすると再生成されます。その際に、Activityのクラスのインスタンスは一度破棄されて再び作られますが、この再生成を超えてデータや状態を保持する必要があります。

Activityには、そのための仕組みonSaveInstanceStateが備わっていますが、データの保存と復元の処理を適切に書く必要があり、コードが複雑になりがちです。

また、破棄される前のActivityへの参照を保持している場合や、コールバックなどで非同期処理を待っている場合は、それらがメモリリークの原因になり得ます。

Activity間のデータの同期

それぞれのActivityで実装された画面同士は独立しているため、それぞれのActivityが保持しているデータ間の同期を行う必要がある場合は、少し面倒です。

例えば、SNSアプリケーションでタイムラインから遷移した先の詳細画面で「いいね」ボタンが押されたときに、その「いいね」をタイムラインにも反映させる必要がある場合などです。

アーキテクチャをどのように選定するか?

これまで挙げたような問題が、これから開発するAndroidアプリケーションにどの程度存在するか? もしくは存在しないのか? そういったことを明確にして、アーキテクチャを選択する必要があります。例えば、1人で開発するプロジェクトであれば、複数人で開発するような問題は起きません。

また、導入しようとしているアーキテクチャがそれらの問題をどのように解決してくれるのか? についても、ある程度考えておく必要があります。

さらに、Clean Architectureのようなレイヤーが細分化されたアーキテクチャでは、関心の分離が適切になされますが、小規模なアプリケーションでは細分化を過剰に感じるかもしれません。複数の候補のなかから、自身のAndroidアプリケーションの問題を最もシンプルに解決できるアーキテクチャを選ぶのがよいでしょう。

したがってアーキテクチャを選定する際には、現在どのようなものが主に用いられているかを知る必要があります。次のセクションでは、現在のAndroidにおいて主流なアーキテクチャについて解説します。

現在の主流なAndroidアーキテクチャ

エンジニアHubに会員登録すると
続きをお読みいただけます(無料)。
登録のメリット
  • すべての過去記事を読める
  • 過去のウェビナー動画を
    視聴できる
  • 企業やエージェントから
    スカウトが届く