ViewModel設計の原則 その1

□導入

MVVMの知名度は十分に高まっているものの、MVVMでの開発はまだまだしきいが高いと感じる方が多いのではないかと思います。確かに、MVVMで開発するためのライブラリやフレームワークが出揃い始めており、それらの技術について説明したコンテンツも充実しつつあるように思います。しかし、これらの技術をどう使って設計していけばよいのかはどのコンテンツにもあまり語られていません。特にMVVMの肝であるはずのView Modelの設計をどうしたらよいのかについて説明しているコンテンツがなく、各技術者に任されてしまっています。

私自身、模索を繰り返しながら何とかViewModelの設計をやっているのが実態で、まだまだ不明な点が多くあります。しかし、今まで私がMVVMによる開発を行ってきたなかで得たものを、「View Model設計のための原則」というテーマで、何回かに分けてご紹介したいと思います。いくらかでもMVVMによる開発の参考になれば幸いです。

なお、ここでの説明がどのプロジェクトにも適用可能な正しい内容であるかは分からないことをあらかじめご承知おきください。ここでの内容をそれぞれのプロジェクトで使用するのはもちろん構いませんが、すべて自己責任でお願いします。

□MVVMパターンとは

早速ですが、そもそもMVVMパターンとは何かというと「Model-View-ViewModelパターン」のことです。

MVVMでのModelとは、ビジネスロジックとデータを表現し、一般にドメインモデルと呼ばれたりする"モデル"です。データベースを使用した場合にはORマッピングされるエンティティや、サービスとして実装される部分です。MVVMパターンはGUIのためのパターンであるため、本ブログではあまり説明しませんが、このモデル自体、システムの中でとても大きな位置を占めるので注意が必要です。

MVVMでのViewは、画面コントロール、画面レイアウト、フォント、色彩、アニメーション、UIロジックを表現します。通常はXAMLで実装し、可能な限りコードビハインドは使用しません。これは、XAMLの方が宣言的に画面を定義できるからですが、決してコードビハインドを使用してはならないという訳ではないことに注意してください。

MVVMの最後の要素であるViewModelは、プレゼンテーションロジックを表現し、画面に表示・編集する値をプロパティとして保持し、またボタン押下時などに実行すべき処理をコマンドと して保持します。そして、ViewModelの最も重要な側面として「Model of the View(ビューのモデル)」を表現するというものがあります。つまりViewModelとは画面そのものを抽象化したもの、さらに言い換えると画面そのものをモデル化したものということです。

ViewとViewModelの状態は、常に同期が行われるのがMVVMでの大きな特徴です。この同期は主に データバインドとデータトリガ―の機能により実現します。(ただし、高度な同期についてはビヘイビアを自作する必要に迫られることもあります。)ViewModelの状態変化はViewの状態変化をもたらし、また逆にViewの状態変化はViewModelの状態変化をもたらします。ただし考え方としては、ViewとViewModelは対等の関係ではなく、ViewModelが主で、Viewが従の、主従関係にあると考えた方がよいでしょう。

Viewには画面コントロール、画面レイアウト、フォント、色彩、アニメーションなどの画面のあらゆる要素が存在しています。しかし、これらを細かくコントロールしたくないし、抽象的かつ容易に扱いたいのです。そこにViewModelの価値があります。実は、同期の仕組みにより、画面を抽象化したViewModelに対してプログラミングを行うことで、間接的にViewをコントロールできます。つまり、高い抽象を保ったまま画面をコントロールできるということです。これこそがMVVMのもっとも大きなメリットなのです。

□[原則1]ViewModelをモデリングの対象として認識すること

Viewでは、画面コントロール、画面レイアウト、フォント、色彩を司り、ViewModelでは画面に表示する値やコマンドを司ると前述しました。しかし、「ViewModelにてフォントや色彩を保持してはいけないのか?」というと実はそんなことはないのです。

実は本来のViewModelとは、「あなたが画面において制御したいと考えたもの」です。これはつまり、あなたが画面において何が重要であり、また何を無視すべきなのかを判断したモデリングの結果がViewModelであるということです。

そういった意味において、フォントや色彩が重要であると考えた場合には、ViewModelにこれらが含まれることは全く問題ありません。しかし、確かに多くの場合にフォントや色彩などをViewModelは保持しません。これはどういったことなのでしょうか?例を挙げて説明しましょう。

「期限が迫っている項目を赤く強調表示したい」というストーリーを考えてみましょう。この場合「期限が迫っている項目として強調表示すべきか」ということが画面の意図として重要となります。このため、ViewModelでは強調表示するかどうかのBooleanのフラグを保持することになり、この抽象化されたフラグに対してプログラミングを行い、画面をコントロールします。

一方、強調表示するために、赤くするのか、フォントを変えるのか、アニメーションを行うのか、あるいはその組み合わせを実行するのかは画面の抽象からすると重要ではありません。このためこれはView側の役割となり、データトリガ―機能などでこのViewModelのフラグを監視して、赤くするといったことを実現します。

ViewModelによる抽象化された画面に対するプログラミングの実現と、ViewModelとViewの主従関係とはこういったことを指しています。そして、フォントや色彩がViewModelにて保持されることがあまりないのは、画面の意図のレベルにおいて重要と判断されることが少ないからということになります。

画面そのものをモデル化したものがViewModelであるという考え方は、いくら強調しても強調しすぎることはありません。これは、ビジネスをモデル化してドメインモデルを作成するように、画面をモデル化してViewModelを作成する必要があるということです。漫然と開発してもドメインモデルが 生まれないのと同様に、積極的にViewModelをモデリングしないとViewModelが生まれることもありません。

[原則1]ViewModelをモデリングの対象として認識すること

□ViewModel設計の原則
ここまで、ViewModel設計のl1つ目の原則として「ViewModelをモデリングの対象として認識すること」を説明してきました。今回ブログの最後に唐突ではありますが、本シリーズのテーマとなっているViewModel設計の原則を以下に列挙します。

・[原則1]ViewModelをモデリングの対象として認識すること
[原則2]画面定義後、Viewの実装の前にViewModelの(簡易)設計を行うこと 
[原則3]ViewModel設計を画面設計に位置づけ積極的に設計すること 
[原則4]あらゆる画面の状態をViewModelでの状態としてモデル化すること 
[原則5]イベントではなく、ViewModelの状態によって画面を制御すること
[原則6]いつでもViewを再構成できるだけの情報をViewModelに保持させること
[原則7]ViewとViewModelとは平行なツリー関係を維持すること
[原則8]ViewModelツリーの親子関係は慎重に設計し、親は子に依存しても、子は親に依存させないこと

(※しっかりとまとめきれていないので、今後変更される可能性があります)

これらの原則の詳細は次回以降に説明します。

以上。

人気の投稿