MVVM のバランス──DataBinding を使うのをやめた

以前の記事「LVMC (a.k.a. MVVM: ViewModel + DataBinding) と Fat View」では、使い方を覚えた DataBinding で調子に乗って、何でもかんでも処理を View-Controller 側に詰め込んでしまい、Fat View に陥いるという反省を経た。

結局、MVVM というより DataBinding がイマイチ良くなかった気がする。DataBinding を使おうとすると、どうしても無理してレイアウトで静的に記述しようとするために、その皺寄せを View-Controller 側なり、ViewModel 側なりに押し付けてしまうわけである。以前の記事の時は、DataBinding の皺寄せを、View-Controller 側に詰め込んだのを、ある程度 ViewModel にも分担させるべきだという反省だった。今回は実のところ、ViewModel 側に DataBinding の皺寄せを詰め込み過ぎたのである。

例えば、モデル側から画像のリスト(LiveData)を得てスライダー操作でその中から一つの画像を表示するとする。この場合、DataBinding と ImageView の立場からすると、ImageView は単に DataBinding で記述された静的なレイアウトから src を読んで表示するのが楽である。src がリストから抜き出されて変化するかどうかなどということは、ImageView 側は何も意識する必要がない。

となると、スライダー操作によってリストから一つの画像を抜き出す処理は全てバインドされた ViewModel 側に記述する必要がある。これがやってみると恐ろしく大変な作業で、抜き出される画像は、まず LiveData であるリストの変化を observe する必要があり、さらにスライダー操作によって抜き出すインデックスの変化をも observe する必要がある。こういった形でスパゲッティのように絡み合った observe / observant の LiveData で連鎖する回路を ViewModel 中に記述する羽目になる。

一度、上記のようなスタイルでアプリを構築したのだが、結局リファクタリングの際に見直して、普通に Activity / Fragment 側のイベントリスナーでリストから画像を抜き出す方式に変えたら、スッキリした。ViewModel には普通に LiveData である画像のリストだけを持たせる程度で、Activity / Fragment 側ではそれを observe し、変化のあった場合に現状のインデックスに従って抜き出し直すだけである。スライダー操作による抜き出しインデックスの変化をわざわざ遠回りして ViewModel を経由させるようなことはしないで、オーソドックスに View-Controller(Activity / Fragment)内のその場で処理させるやり方の方が断然スマートであると痛感した。

何もかも諸悪の根源は DataBinding である。ViewModel や MVVM が悪いのではない。

ViewBinding はすごくお勧めなのだが、DataBinding はもう使いたくないと思った。

まとめ

ViewModel というのは結局、Activity / Fragment のライフサイクルに左右されずに保持したいデータを置く場所として扱えばよく、ネットワーク絡みの処理など非同期的な処理が、Activity / Fragment の同期的な処理と、直接交錯するのを避けて分離するためのバッファとして意義がある。通常のスライダー操作のような View-Controller 側でそのまま処理すべきものをわざわざ ViewModel を経由して LiveData として扱うのは無意味どころか、百害あって一利なし、である。

コメント

このブログの人気の投稿

清水俊史『上座部仏教における聖典論の研究』

シークエンスパパとも 本物の霊能力

シークエンスパパともの先見の明