LIGHT11LIGHT11読者になるLIGHT112019-01-23【Unity】MVPとMV(R)Pの実装例といろんな実装方法の考察UnityUnityでMVPと、UniRxを使ったMV(R)Pを実装してみました。調べたらいろんな実装方法があったのでそのあたりの考察も加えています。全部Viewに書くMVPMV(R)Pいろんな実装があるViewとPresenterは1:1にするべき?PresenterはMonoBehaviourにするべき?Viewはインタフェースにするべき?ViewはModelを知るべき?参考まずは全部Viewに書くまず、アーキテクチャを使わない状態、すなわち全ての処理を一つのクラスに書いたものを作ってみます。}}押すたびにGemの数がインクリメントされて保存され、ボタンに表示されます。処理が増えるにつれて複雑なクラスが出来上がっていきます。MVPつぎにMVPの設計方針に従い責務を分離してみます。Viewの責務でない部分をPresenterに移します。今回の例におけるViewの責務は、テキストの更新とクリックイベントの通知なので、これをPresenterに移します。}}クリックされた時のイベントはPresenterに通知しているだけで、実際の処理は行いません。Viewの更新は、更新用のメソッドがインタフェース経由で公開されているだけです。実際にこのメソッドを読んでViewを更新するのはPresenterに任せます。いうわけでPresenterを書いていきます。}}Viewからのクリック通知を受けて実際にGemの数を更新し、Viewを更新しています。これでViewとPresenterを分けることができました。ちなみにPlayerPrefsをいじっている部分などはいわゆるModelですが、ひとまずはViewとPresenterを分離することが重要なので本記事では深くは触れないことにします。MV(R)P次にMV(R)Pを使ってみます。MV(R)PはMVPとUniRxを組み合わせたアーキテクチャです。軽量イベントフックとuGUI連携によるデータバインディングまずViewは次のようになります。}}Viewにはイベントを監視するためのObservableを定義するだけでPresenterの参照は持ちません。MVPと違ってViewのインタフェース定義をしていません。}}PresenterはViewのイベントを監視して、Viewを更新します。今回は書いていませんが、同じようにModelを監視することでModelの変更を受け取ります。一度監視してしまえばあとは勝手にModelに紐づいてViewが更新されるのでいい感じです。いろんな実装があるMVPとMV(R)Pについて、標準的だと思われる実装を前節までで紹介しました。これらのアーキテクチャについて調べると、実装や考え方が微妙に異なっていることがわかります。ViewとPresenterが1:1のものと多:1のものがあるPresenterがMonoBehaviourを継承しているものとしていないものがあるViewのインタフェースを定義する場合と直接参照している場合があるView用のModelを定義しているものとしていないものがある以下ではこれらについて見ていきます。ViewとPresenterは1:1にするべき?MVPやMV(R)Pの実装を見ていると、1つのViewに対して1つのPresenterを定義しているものと、1つのPresenterが複数のViewを管理しているものがあります。上述のMV(R)PのようにPresenterからViewを取得する場合には複数のViewを持つ実装にもできます。それぞれのメリット・デメリットに関しては下記のスライドにまとめられています。やってみた個人的にはViewとPresenterを1:1にするのは冗長すぎるように感じました。PresenterはMonoBehaviourにするべき?上述のMVPの実装ではPresenterが純粋なクラスであるのに対して、MV(R)PのPresenterはMonoBehaviourを継承しています。MonoBehaviourにしない場合にはnewできるのでテストがしやすくなるメリットがあります。ViewがPresenterを生成することになるので、ViewとPresenterが自然と1:1になります。どんなに簡単なViewでもViewクラスとPresenterをいちいち定義しなければなりません。開発方針にはよりますが、UnityではMonoBehaviourにするメリットは大きいと思います。Viewはインタフェースにするべき?上述のMVPの実装ではViewのインタフェースを定義しているのに対して、MV(R)Pでは定義していません。Viewのインタフェースを定義するとViewをテスト用のものに入れ替えられるのでテストしやすくなります。前節の議論でPresenterをMonoBehaviourにした場合には結局テストはしづらくなるので、Viewのインタフェースを定義するメリットも自然と無くなりそうです。ViewはModelを知るべき?Viewに対応したModelを定義している実装とそうでない実装があります。後者は実装が簡潔になりますが、ViewがModelを知るため依存度は高まります。これに対して前者は実装は比較的冗長になりますが、疎結合になります。この辺りはかなり方針が分かれそうなところです。Architectureのような考え方を適用するといい感じになりそうですが、これはまた別記事で。1はてなブログをはじめよう!halya_11さんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。