web-dev-qa-db-ja.com

MVC:データモデルとビューモデル

ドメインとビューに同じモデルオブジェクトを再利用してはならないというモデルに関するMVCのアドバイスを過去に読んだことがあります。しかし、私はなぜこれが悪いのかについて話し合うことをいとわない人を見つけることができませんでした。

2つの別々のモデル(1つはドメイン用、もう1つはビュー用)を作成し、それらの間でマッピングすると、多くの重複と面倒なマッピングコードが作成されると思います(その一部は AutoMapper )エラーが発生しやすい可能性があります。

コードの複製とマッピングの問題に値する2つの懸念事項に対して別個のモデルを用意する理由は何ですか?

48
Erik Forbes

本質的に、2つのモデルは関心の分離に関するものです。ビューを単一のモデルで機能させたい。ドメインモデルが、ドメインの専門家と一緒に構築した概念モデルを表すようにしたい。 ViewModelには、多くの場合、技術的な制約があります。ドメインモデルはPOCOに関するものであり、表示されるデータ(表示)または永続化されるデータ(DBまたはその他)の技術的制約に拘束されません。

画面に3つのエンティティが表示されているとします。それは私が3つの間の関係を強制する必要があることを意味しますか?または、3つのアイテムすべてを含むViewModelコンポーネントオブジェクトを作成するだけです。別のViewModelを使用すると、ビューの関心事が私のドメインから分離されます。

45
Jimmy Bogard

どうして? 'ビューにはモデルオブジェクトを使用する機能がないはずだからです!

プロジェクトをWebデザイナーに渡して、ビューレイヤーを作成するとします。突然、彼/彼女はモデルレイヤーを介してアプリケーションのデータをいじくり回すことができます。それは良いことではありません。

したがって、メソッドを持つオブジェクトではなく、常にビューに必要なデータのみを渡します。

6
Henry

J.P. Boodhooの記事 Screen Bound DTO は、設計上の利点を理解するのに役立ちます。

私が書いた セキュリティ上の利点 もあります。

プレゼンテーションモデルがあると、ビューが簡素化されます。ビューは通常、テストが非常に難しいため、これは特に重要です。プレゼンテーションモデルを使用することで、多くの作業をビューからドメイン->プレゼンテーションモデルに移動できます。フォーマット、null値の処理、オブジェクトグラフのフラット化など。

余分なマッピングが面倒であることに同意しますが、特定のコンテキストで両方のアプローチを試して、何が最適かを確認する必要があると思います。

5
liammclennan

特別にフォーマットされ、確かにヌルセーフであるビューモデルの機能を含む、さらに明白な懸念があります。

2
Matt Hinze

ドメインモデルがMVCアプリケーションだけでなく他の実装にも拡張される可能性があり、それが懸念事項の分離の原則を破るという考えだと思います。ビューモデルISドメインモデルの場合、ドメインモデルを変更する理由は2つあります。ドメイン変更要件とビュー要件変更です。

1
Webjedi

ルールも重複しているようです。

すなわち。 UIでのクライアントオブジェクトの検証、次に検証が必要なドメインオブジェクトへのマッピング。

ただし、私が行う傾向があるのは、ドメインオブジェクトのセットをマップしてモデルを作成することです。顧客情報、在庫情報などを表示するWebページ...私のモデルは、CustomerオブジェクトとStockオブジェクトを保持する構造になります。

CompanyPageModel

public Customer Customer {get;} public Stock Stock {get;}

次に、私のmvcプロジェクトでViewData.Model.Customer.Name ViewData.Model.Stock.CurrentStocks

分離はより多くの作業のように見えますが、後で、UI /ドメインモデルのこの分割を行うのは良いことです...テストを書くようなものです:)

1
Steve

私はついにクールエイドを飲みました。ビューモデルに表示指示をマークして、すべてを自動配線できるのが好きです。

私が今要求しているのは、pocoエンティティからのビューモデルのある種の自動ジェネレータです。私は常にいくつかの文字列をintとして設定しますが、それを見つけるのに永遠に時間がかかります。痛みが気に入らない限り、オートマッパーなしでこれを行うことさえ考えないでください。

0
MvcCmsJon