http://blogs.wankuma.com/rti/archive/2009/06/23/176383.aspx
WPF の Document と View
の続きです。
「結局こんな書き方がいいよなー」とか言ったら
それってMVVMパターンじゃん
とか、その会話こそが、いつものパターンですな訳ですよ。
僕の場合「結局、こんな書き方がいいよねー」「それってXXパターンじゃん」、「えーっ、そんな名前が付いていたんだねー」っていう展開は良くあります。
で、ViewModel(っていうのね)に相応するオブジェクトを DataContext に突っ込む時にいつも思うのが型の問題です。
前回のコードでは、次の部分が型をチェックするために、View 側から見た ViewModel の型が期待したものと違うような場合は、例外エラーをスローさせました。
以下の部分です。
this.DataContextChanged += (s, e) => {
this.document = this.DataContext as Document;
if (this.document == null) throw new InvalidCastException();
};
つまり Document にキャストできない時に例外エラーになる訳です。
View から見て、ViewModel 側に、ここまで厳密な型チェックをする必要性もないように思うのですが、バインドしたオブジェクトのプロパティが無い時に、どんな挙動をするのかよくわからないですし、this.document 変数にキャストしたインスタンスを突っ込んでおけば View 側で ModelView オブジェクトの値をゴニョゴニョする時に毎回キャストする必要がないので、キャストの処理コストが軽減されるだろうという考えです。
で、つい昨日のことですが View が期待するオブジェクトの型チェックにはインターフェイスの方が適しているように思えてきました。
つまり、HogeHogeView を作る時に、同時に IHogeHogeViewModel もセットで作ります。
View 側のコンストラクタには上記と同様なコード(以下)を記述しておきます。
this.DataContextChanged += (s, e) => {
this.model = this.DataContext as IHogeHogeViewModel;
if (this.model == null) throw new InvalidCastException();
};
View に突っ込むことがわかっているオブジェクトは IHogeHogeViewModel インターフェイスを継承する慣習を作れば、互換性はコンパイラが解決してくれる問題になります。
View に突っ込む時は、事前にキャストした状態で突っ込むか、そのまま突っ込んで互換の無い型なら例外エラーを出すことで安全性が保たれます。
・・・とか思ったわけですよ。