UIパターンとMVVMパターン
プログラミング作業を軽減するために、いろいろな方法が考えられています。プログラミングパターンもその手法の1つです。作成するプログラムをうまく考えられた同じパターンで作ることで、作成したプログラムの再利用しやすくする、バグを発見しやする、修正しやすくすることが期待できると言われています。
グラフィカルUIを持つアプリケーションを作成する際に用いられるプログラミングパターンをUIパターンと呼びます。
C#では、MVVMパターンと呼ばれるUIパターンを使用すると効果的と言われています。
現在、C#では、開発ターゲットごとに開発環境が別れています。そこで、開発環境ごとに使用するテンプレートもクラスも異なる場合があるので注意が必要です。 ここでは、特に、WPFを使用したデスクトップアプリケーションに焦点を置き、MVVMパターンを使用してグラフィカルUIを持つアプリケーションを開発するための情報を整理していきたいと思います。
違和感
個人的には、MVVMパターンの考え方は、説明しにくい違和感を感じます。
推測ですが、ブラウン管から、液晶ディスプレイに変化した頃、ディスプレイ解像度が変化したことで、Formアプリケーションで、 異なる解像度のディスプレイに対応できなくなり、Formアプリケーションをブラウザ上で動作するアプリケーション(WPFでは、Pageアプリケーション、あるいは、ASP.Netのようなサーバ上で動作し、ブラウザで操作するアプリケーション)に移行した際のプログラミング現場からの対応の1つではないかと推測しています。
その後、Windowsフォンやタブレット端末が登場し、さらに多くのが大きさと解像度に対応する必要が出てきました。
Windows上で動作するアプリケーションの究極の形は、オフィスアプリケーションや、Adbe社のillustratorやCorel Draw、CADアプリケーションのような巨大アプリケーションのように、マクロ機能を搭載したアプリケーションと推測できるのですが、 MVVMパターンには、マクロ機能やUndo、Redo機能を実装するための分離についての配慮は含まれていない気がします。
UIとプログラミングの分離
プログラミングパターンも含めて、開発手法と呼ばれるプログラミング開発作業の軽減方法は、多人数による手分け作業でのプログラミングを想定して考えられています。WPFでは、UIのデザインとプログラミングを分離しました。xamlと呼ばれるXMLで表記したUIのデザインとC#のプログラムを分離しました。そのことで、UIのデザインをプログラマーではなく、デザイナーが行えるようになりました。プログラムは、UIとは別に作成しておき、後で、UIと組み合わせることで、プログラマーをUIのデザイン作業から開放することができます。このことで、UIデザインが、頻繁に変更されても、プログラムの修正部分を限定することが可能になります。
WPFで導入された、UIのデザインをxamlと呼ばれるXMLで表記する方法は、それ以降に提供されたデスクトップアプリケーション以外の開発ターゲット向けの開発環境でも採用されています。
UIとプログラムは、分離されました。しかし、ほとんどのアプリケーションでは、プログラムの結果から、UIを操作、変更する必要があります。まだ、プログラムは、UIから、独立できません。
そこで、MVVMパターンでは、UIに影響を受けないプログラム部分(Model)とUI部分(View)、プログラムの結果からUIを変更するプログラム部分(ViewModel)に分割することで、UIを変更する際、プログラムの変更が必要な箇所を限定するためのプログラミングモデルです。
本来、チーム開発向けの開発モデルなので、個人が一人で、プログラムを開発する際には、導入してもあまり利点はないと考えてしまうかもしれません。だだ、現状、UIを便利にするための拡張ライブラリのほとんどが、MVVMパターンを使ったプログラムで使用されることを期待して作成されています。MVVMパターンに準拠していないプログラムでは、これらの拡張ライブラリの使用が困難になると思われます。UIに関する拡張ライブラリを使用する可能性がある場合は、MVVMパターンに準拠したプログラミングを行ったほうが良いかと思います。
緩い結合
C#における大規模プログラミングやデザインパターンの説明では、頻繁に「緩い結合」、「弱い参照」が登場します。
この「緩い結合」と表されるものは何なのでしょうか?
この表現は、メモリを自動的に開放する仕組み、つまり、ガーベージ・コレクションの動作を示しています。
- 緩い結合:ガーベージ・コレクションの動作の対象になる。つまり、ガーベージ・コレクションによって、メモリから開放されます。
- 強い結合:ガーベージ・コレクションの動作の対象にならない。つまり、ガーベージ・コレクションの動作の対象にならずに、メモリを専有し続けます。
これが、示しているのは、開発言語に、ガーベージ・コレクションを持つC#を使用してもメモリリークの問題が、依然存在することです。そして、C#では、明示的にメモリの解放を行うことは稀です。
プログラミングの段階から、ガーベージ・コレクションがきちんと動作するプログラムを作成する必要があります。つまり、緩い結合で構成されたプログラムです。
特に問題になるのがイベントリスナーです。イベントリスナーで監視すると強い参照となり、イベントリスナーからの登録を削除しないとガーベジコレクションが動作しません。言い換えるとメモリリークが発生します。
MVVMパターンに準拠したプログラミング
どうやって、MVVMパターンに準拠したプログラミングを行えばいいのでしょうか。MVVMという用語は、C#のプログラムに関する情報を探しているとよく見かけますが、どうやってプログラミングすれば良いのかは、あまり紹介されていません。
いろいろ調べてみると見つけることができると思いますが、MVVMパターン用のフレームワークを使用する必要があります。現時点では、「Prism」 が頻繁に更新されています。現在は、ほぼ更新が止まっていますが、「Prism」より機能がシンプルな「MVVM Light Toolkit」もサンプルプログラムやドキュメントが豊富です。MVVMパターンに準拠したプログラミングを行いたい場合、MVVMパターン用のフレームワークは、他にも存在しますが、結局のところ、「Prism」 と「MVVM Light Toolkit」のどちらかを選択し、サンプルプログラムとドキュメントを探索していくことになります。
Prism
MVVMパターン用のフレームワーク、あるいは、拡張ライブラリです。nugetに対応しているため、Visual Studioから、インストール可能です。
前バージョンのPrism 5と、現行のPrism6で大きく変化しました。もともと、バージョンの変化で動作しなくなるなどの脆弱性がありましたが、Prism 6では、名前空間なども含めて変化しました。 Prism 6は、現状、チュートリアルやドキュメントが弱いので、サンプル・プログラムから内容が理解できないと、習得が難しいと思います。とは言え、前バージョンのPrism 5を新たに習得する意味はありません。
プログラムを作成する際には、WPFテンプレートはそのまま使えません。かなり修正する必要があります。テンプレートとして保存しておきましょう。
Prism 5.0 for WPFのHello Worldを実行する(改修版)
テンプレートパックが存在するので、それを活用する方法もあります。
C#向け、MVVMフレームワークPrismのドキュメント
MVVM Light Toolkit
ドキュメントやチュートリアルが、まとまっている印象があります。プログラミングになれていない方は、Prismより、MVVM Light Toolkitから始めたほうが良さそうです。
NuGetに対応しているため、Visual Studioから、インストール可能です。
Livett(リベット)
UIパターンについてのドキュメント
関連書籍
アプリケーションの構造設計は、理解するためには、幅広い知識と経験が要求されます。プログラミング初心者は、存在することだけを認識していれば良いかと思います。