Modelとまったく同じViewModelを追加することをお勧めします


16

ソリューションに次のレイヤーがあります。

  1. App.Domain
  2. App.Service
  3. App.Core(これをApp.DataLayerと呼ぶかもしれません)
  4. App.Web

ソフトウェア設計パターンは私の質問ではなく、次のモデルがあります Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

ビュー(たとえば、ホームページ)でこのモデルを使用しId, Name & Value、さらにを使用したいので、ViewModelを作成する場合は、次を追加します。

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

だから、それは良いアイデアですか?または単に?のFoo代わりに使用しFooViewModelます


これが理解できるかどうかわかりません。はModel通常に渡されませんViewか?なぜ正確にあなたがのフィールド再作成する必要がありますModelではView?懸念の分離が目標であるMVC場合、どのような状況でModelandで同じことをしたいでしょう Viewか?もしViewModel、両方のはなぜ両方ではない構成/拡張することにより、ModelおよびView
null

svidgenの答え@上で私のコメントを読んでください
メフディDehghani

関連する問題があります-モデル(およびデータベース)の検証(必須属性)で特定の値を入力する必要があることを示していますが、ビューではこれらの値を入力する必要はありません。モデルは、モデルを直接参照するのではなく、ビューモデルに組み込みます。しかし、これを考えると、これはおそらく問題ありませんし、実際には異なる目的のためであるためDRYに違反しません(とにかくそれほど悪くはありません)。
-niico

回答:


20

これは最初はDRYルールに違反しているように見えるかもしれませんが、何か異なることをしたり、独立して変更できる場合、「類似した、さらには同一のコード」は必ずしも「繰り返し」ではないと主張します。また、ビューモデルの場合、コードは「クライアント」が見るものを定義します。必ずしもビジネスが話すエンティティやオペレーションではありません。そのため、多くの場合、「偶然同一」のようなモデルをクライアントまたはインターフェイスに公開しています。ビジネスルールとビジネス用語、またはエンドユーザーの用語を互いに独立して変更できます。

だから、私はあなたに質問を返します。ドメインが変更された場合、「バージョン1」クライアントが古いインターフェースを引き続き使用することは許容されますか?「コアビジネスルール」の一部ではない用語や操作をインターフェイスで公開することはありますか?およびその逆?

ビューの「機能」が厳密に基礎となるドメインモデルを明らかにすることである場合、そういう質問を念頭に置いて、はい、これはDRY規則に違反しているように見えます。

また、モデルの変更に伴ってより自然に変化するビューを公開することは、メンバー属性とリフレクションを使用する一部の言語でも実現できます。(または他の巧妙な偉業を通しての繰り返しが少ない ...しかし、「賢さ」はしばしば、あなたを免れる繰り返しを正当化することに失敗します。)


素敵な言及されたメモ(これに投票)、前の答えのコメントとして言ったように、私は一般的な目的、イメージングについて話している、おそらく数日後に、新しいフィールド/プロパティを追加することを決めたFooのでFoo、ViewModelとして使用した場合クライアントも新しいプロパティを取得するので、この新しいプロパティがセキュリティフィールドである場合(許可の場合はtrue / falseなど)、どうすればよいですか?
メフディDehghani

@mehdiでは、追加しようとしているフィールドと、そのフィールドがビューに属している、または属していないと考える理由をより具体的にする必要があります。または一般的に、懸念はそこにあります。
svidgen

@mehdiを明確にするために、エンドユーザーがセキュリティ値を変更することを心配している場合、ドメインではユーザーが保存する権限のないものを保存できないようにする必要があります
-svidgen

ViewModelを使用する理由 私たちが知っているように、いくつかの理由があります、それらの1つはセキュリティのためです。たとえば、ではUser edit formIsAdminこのフィールドを安全に保つためにクライアントにフィールドを渡す必要がないので、これが心配です。私の悪い英語でごめんなさい。
メディディハニ

1
言い換えると、元の質問は完全な質問だと思います。ここのコメントで把握しようとしている質問は、もう1つの完全な質問です。また、コメントは、質の良い回答を得るための良い方法ではありません。
svidgen

2

Fooインスタンスという1つのプロパティのみを含むビューモデルがあります。そうすれば、Fooが変更されてもビューモデルが自動的に変更を認識し、ビューモデルがモデルに直接結び付けられることはありません。その定義に従ってDRYに違反することはありません。

明日、Fooだけでなく他の何かを表示するビューが必要な場合は、新しいプロパティを追加するだけで、ビューモデルの意図が明確になり、Fooなどが含まれます。 Fooのプロパティと、関連のない他のプロパティの混合。

私はあなたのビューモデルをFooViewModelとは考えないでしょう、私はビューが何を表示することになっているのかという観点から考えます。Fooを1つだけ表示する場合、ビューモデルには1つのプロパティ、Fooが含まれます。

それを明確に説明したかどうかはわかりません。そうでない場合はお知らせください。起きているときに書き直します。


-2

FooViewModelこのように使用すると、DRYプリンシパルに違反することになります。変更する必要がある場合は、変更するFoo必要もありますFooViewModelFooビューのモデルとして単純に使用する方が良いと思います。Fooからのものやその他のものを表示する必要がある場合は、ビューモデルを検討します。たとえば、あなたからいくつかの情報をレンダリングする必要があると言うFooともからBar


に別のフィールド/プロパティを追加することにした場合、私もViewModelとしてFoo使用Fooしたため、この新しいフィールドをビューに渡す必要があると教えてください、これは本当に良い取引ではないと思います、あなたはどう思いますか?
メンディデガニ

ビューがモデルによって公開されたデータのサブセットのみを使用することに何の問題もありません。私は大きいのファウルが間の結合だと思うFooFooViewModel。一般に、単一の論理変更のために複数のファイルを変更する必要はありません。
zero_dev

追加されたフィールドが、true/false許可の値などのセキュリティフィールドである場合はどうでしょう。
メディディハニ

ビュー自体にそのようなフィールドを公開する必要はありませんが、悪意のあるユーザーがそのような変更をPOSTしようとした場合に備えて、ユーザーがセキュリティレベルを変更できないようにコードの残りの部分を確認する必要があります。
グラハム

大量割り当て攻撃に対してオープンであるように聞こえます
ジェームズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.