MVVM と Fat View(その 2)

10 ヶ月前の記事「LVMC (a.k.a. MVVM: ViewModel + DataBinding) と Fat View」でも、Activity からコードを追い出すのに夢中になっているうちにいつの間にやら Fat View になってしまった話をしたが、最近また同じ症状に陥ってしまった。

今回の場合は、「Activity からコードを追い出す」という状況ではなかったせいもあって、当初気付かなかったのだ。

ImageView に Glide を使ってネットワークから画像を読み込む機能を追加した自前のライブラリーモジュールを作っていて、ViewModel から DataBinding を通じて url 文字列さえ与えれば、ImageView が url から読み込んで表示する。そんな風な設計にしていたのだが、「ライブラリーだし、色々なプロジェクトで使い回す場合に、少しでもコードを省けるように」と、Glide を利用したネットワークからの読み込み処理の部分を、ImageView を継承したカスタム ImageView に追加で盛り込んだ。

しかし、正解としては、ViewModel から DataBinding を通じて与えるのは、url ではなく、Bitmap の方が良い。というのも、そうすれば、ImageView は、それがネットワーク上の画像なのか、ローカルにあるリソースなのか、を意識せず、ただ、layout.xml の app:bitmap="@{viewModel.bitmap}" を見て反応すればいいだけである。url 文字列ならダウンロードする、ローカルなら setImageResource() する、などと処理を分岐させる必要がないのである。

当初 url で実装した時には、わざわざ loadImageUrl() なる専用のメソッド・プロパティを用意して動作するように実装したが、後でローカルの画像を使おうとした場合に setImageResource() と使い分けなけばならないことに気付いて、url 文字列ではなく Bitmap をデータバインドして ViewModel と連絡すべきだと気付いたのである。

もちろん、そうなると、ViewModel 側で Glide を使ってネットワークから画像をダウンロードする部分は、プロジェクト毎に記述する必要は出てくる。しかし、MVVM のコンセプトからすると、Glide によるネットワーク処理部分や Bitmap オブジェクトの保持は ViewModel に所属させ、ImageView の方は必要以上に肥大化させて判断処理させるようなことは避けるべきだろう。

今回得た教訓は、ViewModel 側と View 側でどのように割り振ればいいかというバランス感覚の点では、layout.xml の DataBinding で統一的に扱えるようになるライブデータはどれなのか(今回の場合は url 文字列ではなく Bitmap)を基準に考えればいいということである。

コメント

このブログの人気の投稿

EP-805A 廃インク吸収パッド交換

m3u8 ファイルをダウンロードして ffmpeg で MP4 に変換・結合

WZR-HP-AG300H with OpenWrt