質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MVP

MVP(Minimum Viable Product)とは、「必要最低限の機能を兼ね備えた製品」を指します。企画書などを完成させる前に、とりあえず製品を形にする方法です。プロトタイプなどで一旦アウトプットさせることにより、無駄なコストや時間を削減できます。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

2002閲覧

MVP設計の依存性について

memories

総合スコア7

MVP

MVP(Minimum Viable Product)とは、「必要最低限の機能を兼ね備えた製品」を指します。企画書などを完成させる前に、とりあえず製品を形にする方法です。プロトタイプなどで一旦アウトプットさせることにより、無駄なコストや時間を削減できます。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

1グッド

3クリップ

投稿2018/01/27 03:00

主にUnityでの開発を最近学び始めたのですがMVP設計の依存性についてわからない箇所があるのでご教授お願いしたいと思います。

MVP設計では通常以下の形式になると思います。

Model   ←  Presenter  →  View             ⇨                  ⇦ →が依存 ⇨が変更を通知

この時PresenterがViewとModelを扱う上位レイヤーであるため、依存性逆転の原則からして上位レイヤーのPresenterがViewとModelに依存するのはあまり好ましくないのでしょうか。
またもう少し具体的に考えた時、Viewが増えた際に毎回Controllにも大幅に手を加えなければいけないのは若干好ましくないように感じます。
よって上位レイヤーは抽象に依存させるよう考えると以下の形式になるのではなると思いました。

Model   ➡️  IModel                   ↑⇩                Presenter                   ↓⇧                  IView ⬅️ View →が依存 ⇨が変更を通知 ➡️が継承 (分かりづらくてすみません)

この形であればModelとViewの方がPresenterに依存するようになると思うのですがどうにも自信が持てずにいます。
何か私の理解で間違っている箇所、及びこの形の問題点等あればご教授よろしくお願いします。

Hawn👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Viewが増えた際に毎回Controllにも大幅に手を加えなければいけないのは若干好ましくない

これを抽象化で解決するのは正しい方法の一つです。
しかしそれは依存性逆転ではなく、汎化による共通化をしているのです。

MVCについて

MVCやMVPで最も重要なのは、"Modelが他に依存しないこと"です。
その理由は、"変更の多いモジュールが変更の少ないモジュールに依存すべき"だからです。

そしてもう一つ重要な概念として、ModelとViewを分けるフレームワークでは、
"Viewがモデルのデータを取ってくるタイプ"と"ModelのデータをViewに配信するタイプ"、があります。(複合タイプもあります)

上の2つを合わせて考えると以下のようになります。

Viewがモデルのデータを取ってくるタイプ:
Model ← View
変更の多い方が変更の少ない方に依存しているので問題ない

ModelのデータをViewに配信するタイプ:
Model → View
変更の少ない方が変更の多い方に依存してしまっているのでまずい。

そこで間にControllerを入れることでViewの変更がModelに影響しないようにする。
Model ← Controller → View
これも立派な依存性逆転です。

依存性逆転について

依存性逆転を行う理由は2つあります。
一つは、"変更の少ない箇所が変更の多い箇所に依存しないようにするため"です。
これは、MVCのようにクラス間の依存性で解決できます。
もう一つは、"部品を交換可能にして再利用するため"です。
これには多くの場合インターフェースが用いられます。

部品交換の目的を持たない場合、インターフェースはただの"公開メンバ一覧"になり、
公開メンバを追加編集するたびに、インターフェースとクラスの両方を記述するという意味のない作業を行うことになります。
MVCのそれぞれについて、抽象化すべきかどうか考えてみましょう。

** Model **
"変更の少ない箇所が変更の多い箇所に依存しないようにするため"の視点から見ると、Modelを抽象化する必要はありません。
なぜならModelとControllerの関係は始めから、変更の多い方から変更の少ない方への依存になっているからです。
また、インターフェースは呼び出し側が持つものなので、呼び出し側(Controller側)のIModelの定義に合わせてModelを実装すると、依存性が悪い方向に逆転してしまいます。

"部品を交換可能にして再利用するため"の視点からも、Modelを抽象化する必要はありません。
なぜならModelとはアプリケーションの核となるビジネスロジックなので、これを交換することはありえないからです。
ガワ替えは接続先のデータベースの変更で、
接続方法の変更はModelではなくコンポーネントの交換で、
Viewを他のアプリで使いまわすのはViewの機能分割です。
どれも"Modelの交換"ではありません。

** View **
"変更の少ない箇所が変更の多い箇所に依存しないようにするため"の視点から見ると、Viewを抽象化する意義は微妙です。
なぜならViewはもともと変更の多いモジュールだからです。

"部品を交換可能にして再利用するため"の視点から見ると、Viewを抽象化する価値はありそうです。
異なるプラットフォームに対応する際にまるごと交換することができますし、
2Dのゲームを後々3Dに移植することなどが容易になります。
ただ、開発段階から手入力で抽象化を行うことには少し待ってください。
交換する対象もないのに定義を2重で書くことに意味はありませんし、
インターフェースの抽出は完成後にツールを使って一括で行うことができます。

** Controller **
"変更の少ない箇所が変更の多い箇所に依存しないようにするため"の視点から見ると、Controllerを抽象化する意義も微妙です。
理由はViewと同じく、変更の多いモジュールだからです。

"部品を交換可能にして再利用するため"の視点から見ても、Controllerを抽象化する意義はほとんどなさそうです。
なぜならControllerは誰からも参照されていないので、交換することができないからです。
Viewがコントローラーを参照する場合や、Viewとコントローラーが相互依存するフレームワークなども見かけますが、
Modelに強く依存したControllerを交換することはModelを交換することと同じなので、
やはりControllerを交換することはできなさそうです。

まとめ

・Modelが他に依存しない限り、残りの依存性は開発するアプリケーションによって柔軟に変えていけばよい
・交換しない部分を抽象化しても、定義を2重に行うことになり意味がない
・交換のための抽象化は、開発完了後にツールで行えばよい

以上です!

投稿2018/01/28 03:33

Ushimaru

総合スコア69

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

memories

2018/01/28 11:01 編集

ご回答頂き有難うございます。 私なりに以下のように解釈させて頂きました。 - 重要なことは変わるものを変わらないものから切り離し,  変わるものを変わらないものに依存させること - インターフェースによる抽象化を行うのはその部品が交換可能な場合に有効 概念的にはご教授いただきましたので、実際に具体的なクラスをModel、View、Controllerに落とし込んで考えてみようと思います。 改めて本当に有難うございました。
Ushimaru

2018/01/28 23:15

一番重要な部分をきちんと理解されているようなのでよかったです! 開発中に「これってMVC的にどうなの?」と考えることは良いことですが、「MVCってなんだ・・・」のようにどツボにはまりやすくもあります。 実際に作ってみて、「ここを変更するたにびに毎回あそこも変更するの面倒だな」と感じたら依存性の整理を考えてみる。 くらいのスタイルで気楽にやるのがよいと思います。
memories

2018/01/29 11:40

デザインパターン然りMVC然りですが無理にパターンに当てはめるのではなく、その形が適している場合に有効に用いれば良いということですね。 初期設計も大切ですが開発中の設計整理も重要だと感じさせて頂きました。 本当に有難うございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問