LCL Engineers' Blog

バス比較なび・格安移動・バスとりっぷを運営する LCLの開発者ブログです。

AndroidアプリにViewModelを導入した

Androidアプリ兼バックエンドエンジニアの高橋です。(肩書き長い...!)

GW終わってしまいましたね。自分は特に予定も立てていなかったので近場を散策したりMr. Robotという海外ドラマを見たりして時間を潰しました。

Mr. Robot、主人公がハッカーの話で面白そうと思って見たのですが、自分の知識では何をやっているのかさっぱりでした...

この話が理解できるくらいの(ホワイトな)ハッカーになるべくこれから精進してまいります。

さて、入社してから2週間ほどAndroidアプリ版バス比較なびの開発をこなしてきたので、Androidの技術的な話がブログに書けるようになってきました。

今回はアプリのアーキテクチャをMVVMにしたという話をご紹介します。

現状のアーキテクチャ

現状のアーキテクチャを大雑把に図にすると、こんな感じになっています。 f:id:ktx_ku:20190426125658j:plain

流れを解説すると、Activity/FragmentからRepository経由でAPIもしくはローカルDBからデータを取得し、Modelオブジェクトに包んでViewに反映している形になります。

要は取得したデータをViewに垂れ流しているだけですね。

使用している主なライブラリとしては、

  • APIクライアント → Retrofit
  • 非同期処理 → RxAndroid
  • Viewへの反映 → DataBinding
  • ローカルDBのORM → GreenDao

などです。

現状の課題点

しばらく上記のアーキテクチャに沿って実装をしていたところ、いくつか辛い点が出てきました。

  • Viewの現在の状態を取得できない (もしくはしづらい)。
  • データの持ち回りがActivity、Fragment間でしづらい。
  • Activity、Fragmentにデータ操作のロジックが入ってきてしまいクラスが肥大化する。

これらは全て、APIやローカルDBから取得したデータを保持する場所が明確になっていないことが原因です。

どうしたか

これらの問題は、ViewModelを導入すれば解決すると考えました。

つまりMVVMな構成をちゃんと作りましょう、という事ですね。

ViewModelを導入すると、先ほどの図はこんな感じになります。

f:id:ktx_ku:20190426153907j:plain

Activity/FragmentとRepositoryの間にViewModelが入りました。

このViewModel内では主に以下の責務を担います。

  • Repositoryを通じてデータを取得
  • 取得したデータの保持
  • Viewに反映するためにデータを加工
  • データを監視可能にする

最後のデータを監視可能にするのは、Viewの更新を容易にするためです。

監視可能にする事で、Viewを更新するときはViewModelの値を更新するだけでよくなります。

監視可能にする方法はいくつかありますが、今でいうとLiveDataがいいと思います。

developer.android.com

これでデータの保持する場所が明確になり、Activity/FragmentはViewModelだけ気にすればよくなりました。

ちなみに、ViewModelはAndroid Architecture ComponentのViewModelを使うと、Activity/Fragmentのライフサイクルを考える必要がなくなって楽です。

公式にガイドもあるので導入しやすいと思います。 developer.android.com

やってみて

まだ一部の画面にしかViewModelを適用できていないので、課題に感じていた点に関しては効果をそこまで感じていませんが、データの処理をしていたコードが全てViewModelに行ったので、責務の分離ができています。

また開発の指針ができたので、今後新しい機能が追加される時に開発がしやすくなると期待しています。

最後に

AndroidにおいてMVVMアーキテクチャはかなり一般的になってきているので、まだやった事がないという方は是非トライしてみるのがいいと思います。

今回はサンプルコードなしで概念のみの説明となってしまいましたが、調べればたくさん記事があるので、概念さえわかれば導入自体はそこまで難しくないと思います。

LCLではプロダクトの課題を改善していきたいエンジニアを募集中です! www.lclco.com