目次
MVPパターンの一般的なオブジェクト図です。
- View・・・・・ユーザーインターフェース
- Presenter・・・ViewとModel(Repositoryクラス)の仲介
- Model・・・・データ保持
- Repository・・サーバ、データベース、ストレージなどにアクセスしてデータを取得(図ではデータベースのみ)
- ISession・・・データベースにアクセスするメソッドを定義
そしてViewのインターフェースが必要です。理由は、PresenterがそのままViewに依存する設計だと、Presenterがプラットフォームのフレームワークに依存してしまい、PresenterクラスをUWPやXamarin、Unityといった複数のプラットフォームで使いまわすことができなります。また、Viewのモッククラスを作ることでPresenterクラスをユニットテストすることができるメリットもあるので、MVPパターンではViewのインターフェースは必須です。
MVPパターンのメリット
上記の説明だけだとMVPパターンはView1個につきインターフェースを作らなくてはいけないデメリットがあるのでMVVMやMVCのほうが便利じゃね?という印象ですが、インターフェースを作ることでオブジェクト指向言語の恩恵を受けることが出来るので、その活用例を説明します。
ユニットテストできる
ViewのMockを作ることができるので、Presenterのテストをすることができます。Moqフレームワークを作って簡単に作るのも良いですが、SpyMockを作ってプロパティの呼び出し回数やメソッドに渡される引数などを監視して、表示された回数などを記録するようにすればテストが充実します。
Compositeパターンで合成できる
CompositeパターンとはGoFの23パターンの1つです。Viewのインターフェースをコレクションにしてしまう設計でシンプルに実装すると下記のコードのようになります。
var list = new List<IView>();
Compositeパターンを使えば、簡単にViewを合成することができ、例えば動画編集ソフトの例で解説すると、ユーザーが任意の動画を選択すると動画が再生されて且つ動画のフレーム画像が一覧表示するといった実装で使えます。コレクションを操作するだけで、いくらでも付け外しできるので、ユーザーが動画を選択した場合の処理を後から追加することもできますし、動画を再生するViewがクローズされている場合は動画を再生しないといったことも可能です。
Decoraterパターンで拡張できる
こちらも同様でGoFの23パターンの1つで、ログデコレータ、述語デコレーター、分岐デコレータ、遅延デコレータ、プロファイリングデコレータなどでViewを拡張でき、さらにコードを再利用できます。例えば、Viewが表示されたことをログに記録するコードが必要な場合、ログデコレータで作っていれば、テストプロジェクトとアプリケーションプロジェクトで、ログ記録のコードを使い回すことができます。当然、マルチプラットフォーム開発でも使えるので、同じログ記録のコードが複数存在することがなくなります。
MVVM と MVP の使い分け
GUIアプリケーションのアーキテキチャとして有名なのがMVVMパターンです。このアーキテキチャとMVPパターンを比較すると
MVVMはデータバインディングが得意でデータとViewを紐づけるのが得意
MVPはアニメーションなどのメディア関係のViewが得意
なため、MVVMはツール系、MVPはゲーム系で採用される傾向にあります。
注意して欲しいのが、MVVMかMVPで統一するのではなく適材適所で使ったほうが良いです。所感ですが、ユーザーインターフェースが複雑でViewのモックを用意してユニットテストする必要があるレベルであれば、MVPパターンで実装して、それ以外はMVVMで実装するのがベストじゃないかなと思います。