web-dev-qa-db-ja.com

ビューとモデルは通信すべきか?

MVCアーキテクチャのウィキペディアページ によると、ビューはモデルから自由に通知され、モデルの現在の状態についても自由にクエリを実行できます。ただし、 Paul HegartyのiOS 5スタンフォードでのコース、講義1、18ページ によると、すべての対話はコントローラーを経由する必要があり、ModelとViewはお互いを決して知りません。ヘガティの発言がコースの簡略化として意図されているべきかどうかは私には明らかではありませんが、私は彼がそのようなデザインを意図していると言いたくなります。

これらの2つの反対の観点をどのように説明しますか?

33
Stefano Borini

これはMVC/MVVMで議論の余地のあるトピックです。ビューがモデルに直接アクセスしても問題ないと言う人もいれば、ビューからモデルを抽象化するには、モデルをViewModelsにラップする必要があると言う人もいます。私は個人的にどちらのアプローチも好きではありません。

MVC/MVVMの主な目的の1つは、UI、ビジネスロジック、およびデータを分離することです。その概念を念頭に置いて、ビューがモデルに直接アクセスできるようにすると、必要のない依存関係が作成されます。一方、ViewModelでのモデルのラップは面倒で、あまり有用ではありません。ViewModelは単にモデルへのパススルーとして機能する傾向があるためです。

私はあなたのモデルに特定のインターフェースを実装させるアプローチが好きです、それをIModelと呼びましょう。その後、ViewModelクラスは、Viewを使用するためのIModelを実装するオブジェクトのインスタンスを提供できます。 Viewは、ViewModelから取得したIModelオブジェクトで動作することを知っているだけです。これにより、無関係なViewModelラッパーコードが削除され、IModelの具象実装がViewから隠されます。後で1つのビューに影響を与えることなく、IModelの1つの実装を別の実装に交換できます。

26

Webでは、誰もが自分のデカップリングMVCを呼び出します。

C#などの一部のテクノロジーはMVVMを使用します。これは、Viewと他のテクノロジーとの間にリンクがないため、すべてがサービスロケーターを通過して変数をバインドするためです。

純粋なMVCでは、ビューはモデルと直接対話し、その逆も同様です。コントローラーは、変更が発生したときにのみ存在します。

そして、PAC(Presentation Abstraction Control)と呼ばれるものがあります。このアーキテクチャでは、ビューとモデルは互いに通信しません。コントローラは、ビューまたはモデルのいずれかで何でもできる唯一のコントローラです。人々はしばしばこれをMVCと混同します。

より良い説明がここに表示されます: http://www.garfieldtech.com/blog/mvc-vs-pac

12

私にとって、アーキテクチャの基本的な目標は、それが将来のリファクタリングの試みを妨げないことです。通常、モデルと直接やり取りするビューはこの要件を満たしていますが、そうでない場合は比較的明確です。

ビューがモデルに近づきすぎている場合、ViewModelは美しいものになる可能性がありますが、通常、それが必要とされるインスタンスが少数派である場合があります。

7
menacingly

[〜#〜] mvc [〜#〜]では、Paul Hegartyは間違っています。コントローラーは、モデルからビューへの通信ではなく、ユーザーイベントに関するものです。古典的な[〜#〜] mvc [〜#〜]では、ビューはモデルを観察します(観察者パターン)。

調停をする間に男がいるので、パターンは[〜#〜] mvp [〜#〜]と呼ばれるべきであり、実際、現在MVCとして提示されているもののほとんどは実際により近いMVPに。

次に、[〜#〜] mvvm [〜#〜]があり、両方に似ていますが、少し異なり、ずっと前に存在していました... 2つとして見るのが最善です。 MVC/MVPはviewmodelオブジェクトを介してバインドされています。「クライアント」MVCはモデルとしてビューモデルを持ち、「サーバー」MVCはビューとしてビューモデルを持っています。

6
herby

特にスタンフォード大学の講義の内容について質問しているので、Hegartyのスタンスについて次の2つの点を検討する価値があります。

  1. あなたが言ったように、彼は100レベルのコンピュータサイエンスコースを教えています。彼の講義には、基本を教えるときに必要となるように、彼が簡素化したり、詳細をつぶしたり、「このようにしてください」と言ったりする場所がたくさんあります。つまり、ルールを破る前にルールを習得する必要があります。
  2. IOS SDKでの私の経験は、それがenforceビューとモデル間の厳密な分離を行わない場合、そのパターンに大きく関連しています。特にiOSアプリを作成する場合は、モデルとビューの分離に準拠することで、フレームワークの期待に沿うコードを作成できます。 Hegartyの発言を他のプラットフォームまたは一般的な開発に一般化することはためらいます。
4
Dan J

これには厳格な規則はないと思います。それは完全にあなたのニーズに依存します。

あなたは異なる信念を持つ人々を見つけるでしょう。アーキテクチャは、より良いソリューションの設計に役立つ概念です。

モデルビュー通信とは別に、MVCのビジネスロジックにはもう1つの矛盾があります。多くの人々は、すべてのビジネスロジックが1つのモデルであると信じています( this SO question を参照)。一方、Florianによって共有されたリンク(彼の答え)は、ビジネスロジックはコントローラー上にある必要があります。

これとは別に、ビジネスロジックをアプリケーションロジック(コントローラーに置く)とドメインログイン(モデルに置く)に分割する可能性があります。

したがって、この話の教訓はMVCであり、モデル、ビュー、コントローラーが別々であることを意味します。それ以外は、あなたに一番合うものは何でも。

1
Mohit Leekha

私はポール・ヘガティに同意し、ビューはモデルについて知ってはならないことを信じています。達成することはそれほど難しくありませんが、設計と将来の柔軟性に追加の利点をもたらします。

「ダミー」のViewModelクラスを避けてシンプルにしたい小さなアプリケーション(通常はデスクトップ)では、IModelインターフェースも使用し(上記の回答を参照)、ModelがViewを認識しないようにします(サブスクライバーを使用)古典的なMVCのように)。

また、この場合、コントローラーはビューと完全に結合するようになっています。簡単にするために、必ずしもそれらを明確に分離しているわけではありません。

2番目の「簡略化された」アプローチは、同じモデルに複数のビューがある場合は問題ありませんが、異なるモデルに同じビューを使用する場合はお勧めしません。異なるということは、メインモデルを「たどる」JUnitテストクラスだけでなく、本質的に本当に異なるということです。

1
Dime

モデルビューコミュニケーションにはDTOを使用しています。

例えば:

  • ユーザーが更新フォームに入力する(表示)
  • ユーザーがフォームを送信する
  • コントローラーはフォームデータをUserUpdateDTO にバインドします
    • DTOとUserModelはPOJOですが、ユーザー名を更新できないため、DTOにはIDとユーザー名がありません。
    • もう1つの違いは、Modelクラスには関係と関連付けがありますが、DTOはデータのみを格納し、JSR 303バリデーターを追加することがあります
  • コントローラーは保存するサービスレイヤーにそれを言います
  • サービス層は、データを永続化するようDAO層に指示します
0
Fırat KÜÇÜK