WPFでMVVMを意識して開発していても、
機能追加を続けているとViewModelがどんどん大きくなっていくことがあります。
私自身の現場でも
・Commandが増え続ける
・UI状態プロパティが増える
・一覧画面のロジックが集まる
といった状態になり、
「このViewModel、ちょっと辛くなってきたな…」
と感じたことがありました。
最初は
「ViewModelに書きすぎているのかな?」
と思いましたが、振り返ると原因はそれだけではありませんでした。
実際に感じたのは、
最初に役割分担のベースを決めていないと、処理や状態が自然とViewModelに集まりやすい
ということです。
そこでチーム内で整理した
ViewModel肥大化を防ぐための設計ルールを3つ紹介します。
なぜViewModelは肥大化しやすいのか
WPFのMVVM構造では
・Viewには基本ロジックを書かない
・UIに関係する処理はViewModelに集まる
という前提があります。
そのため、
・UI状態管理
・Command処理
・コレクション操作
・ちょっとした判定処理
などが自然とViewModelに集まりやすい構造になっています。
さらに、
「とりあえずViewModelに書く」
という形で機能追加を続けると、
ViewModelが処理の受け皿になり、肥大化しやすくなります。
実務でよくある肥大化パターン
特に 一覧画面のViewModel は肥大化しやすいと感じています。
例えば次のような機能です。
・ソート
・検索
・絞り込み
・選択状態管理
・画面遷移時の状態保持
これらはすべてUIに関係する処理のため、
自然とViewModelに集まりやすくなります。
実際の現場でも、フォルダ一覧画面などで
・ソート
・フィルタ
・検索
・ページ送り・戻し
・表示状態の保存
・画面遷移
などの機能が追加されるにつれて
一覧画面のViewModelだけがどんどん大きくなる
という状況を経験しました。
1. UI状態は「画面状態」としてまとめる
機能追加を続けていると、
ViewModelに次のようなプロパティが増えていきます。
IsEditMode
IsLoading
IsSaveButtonEnabled
IsItemSelected
IsDirty
一つ一つは正しいのですが、
増え続けると画面状態が散らばり、意味が分かりづらくなることがあります。
そこで見直したのが
UI状態はまとめて管理する
というルールです。
例えば
・画面モードを enum で管理する
・画面状態用のクラスにまとめる
といった形です。
これだけでも
・状態の意味が分かりやすくなる
・ViewModelの見通しが良くなる
という効果があります。
2. Commandは「画面操作の入口」にする
Commandは便利なので、
つい処理を書き足していきがちです。
例えば
・入力チェック
・保存処理
・データ更新
・再読み込み
などをCommand内でまとめて書いてしまうケースです。
最初は問題ありませんが、
機能追加を続けると
Commandの処理がどんどん長くなる
という状態になります。
そこで見直したルールは
Commandは画面操作の入口にする
ということです。
つまり
ボタン押下
↓
Command
↓
処理クラスを呼び出す
という形にしておくと、
・Commandがシンプルになる
・処理の役割が分かりやすくなる
というメリットがあります。
3. ViewModelは「画面の状態管理」に集中させる
機能追加を続けていると、
・状態管理
・処理呼び出し
・データ取得
・UI制御
などが少しずつViewModelに追加されていきます。
結果として
ViewModelが“とりあえず置く場所”になりやすい
という状態になります。
そこで意識したのが
**ViewModelは画面の状態管理に集中させる::
という考え方です。
・画面状態
・Command
・表示用データ
を中心に持たせ、
処理自体は別のクラスに逃がすことで
ViewModelの見通しがかなり良くなりました。
肥大化のサイン
実務で感じたViewModel肥大化のサインは次のようなものです。
・Commandが増え続ける
・UI状態プロパティが増え続ける
・一覧画面のViewModelだけ極端に大きくなる
こうしたサインが出てきたら、
役割分担を見直すタイミング
かもしれません。
まとめ
ViewModel肥大化を防ぐために見直した設計ルール
・UI状態はまとめて管理する
・Commandは画面操作の入口にする
・ViewModelは画面状態管理に集中させる
特にWPFでは、UIロジックがViewModelに集まりやすいため、
最初に役割分担のベースを決めておくことが重要だと感じています。
関連記事(内部リンク)
WPF開発で最初に知っておきたかったこと
MVVMを意識していたのに、ViewModelが壊れ始めた話
WPFで後から辛くなるバインディングの典型パターン3選
WPFでよくあるCommandハマりポイント3選+回避策【初心者でも安心】
シリーズまとめ
今回までで
WPF実務でハマりやすい設計・実装ポイント
を整理してきました。
次回からは
「WPFチーム開発で最初に決めておきたいこと」
というテーマで
・設計ルールの共有
・技術判断の基準
・チーム開発の進め方
など、現場目線で整理していこうと思います。