daisuke_nomura の日記

Android プログラマーな鉄道ファンのブログ

MVPにViewModelを導入した

タイトルの通りである。

ただし、ViewModelは今は、Architecture ComponentsのViewModelを指している。

将来的には、MVVMのViewModelも指すだろう。

MVP

MVPことModel-View-Presenterは、PresenterがModelに処理依頼なりデータ取得を行い、返ってきた値をViewに反映する設計パターンである。 ViewとPresenterは、Contractに定義されたインターフェースを経由してアクセスする。

全体を絵にするならこんな感じである。 PEAKS で販売中の 『Android アプリ設計パターン入門』を参考に作成した。

f:id:daisuke_nomula:20180520185520p:plain

Android界隈はMVVM(Model-View-ViewModel)が流行っているが、設計パターンの基本形として覚えておきたい。

Android アプリ設計パターン入門』 はもちろんマストバイアイテムなので、急いで注文しよう。

peaks.cc

ViewModelを導入

MVPにはない(今はArchitecture Componentsの)ViewModelを導入した。

以下の形になった。

f:id:daisuke_nomula:20180520190019p:plain

モデルから得られ、ViewModelを経由したObservableなりLiveDataは、Presenterでsubscribeすることにした。 これは、Presenterがモデルから取得したデータをViewに反映するMVPの設計に合わせるためである。 ライフサイクル周りは、View(実装はFragment)から提供している。

ViewModel導入は以下の意図があった。

  • MVVMに移行したかったが、データバインディング含めて作業量が膨大なので、一先ずViewModelを導入して少しずつ移行する
  • モデルの内部でデータをキャッシュしているものの、応答に2、3秒間掛かるため、UIに近い所でキャッシュしたかった

作業量が少なかったら、一気に移行しただろう。 目標としては、MVVM化にあたって、ワンクッション置いたのである。

レイヤーが増えた

レイヤーが増えちゃって面倒くさそうと思うだろうが、まさにその通りである。

というのも、きちんとMVPで整理されていたり、既にモデルからObservable/LiveDataを得ているなら、PresenterをViewModelに書き換えるのはそれほど苦労しないと思われる。

ワンクッション置いているので、過渡期な印象は否めない。

また、時期は不明だが、将来的な改修でPresenterはなくなり、ViewModelはMVVMのViewModelも指すだろう。

MVPVM

microsoftのウェブサイトを見ると、MVPVMという設計パターンがあるらしい。

データバインディングを使っており、ココで書いたのとは異なる。

MVPVM 設計パターン - WPF 向けのモデル - ビュー - プレゼンター - ビューモデル設計パターン