ビュー モデル クラスの別のレイヤーが適切な方法であるいくつかのケースを考えることができます。一般的な ORM ツールと一般的な MVC フレームワークの観点からそれらを説明しようとします。これら 2 つのどちらでもないことに注意してください。ケースは、Entity Framework を使用した ASP.NET MVC フレームワークに固有のものです (また、.NET でのプログラミングにも...)。
また、次のいくつかの段落では、ビューモデルのみを具体的に参照していることに注意してください。大量割り当ての脆弱性などの問題については、この記事の最後で説明します。
理由 1: ビュー レイヤーに必要なデータだけを提供し、他には何も提供しない
これはやや「純粋」な目標です。真の MVC アプリケーションでは、ビュー レイヤーはその時点で必要なデータにしかアクセスできず、それ以外には何もアクセスできません。ビュー モデル オブジェクトは、ビュー レイヤーからコントローラーへの仕様になります。 「これは、要求されたビューを表示するために必要なデータです。」基本的な MVC 原則を順守するために、表示するデータに関するすべての決定がコントローラーによって行われるようにする必要があります。
言い換えれば、ユーザーの姓名、ユーザー名、写真を表示したい場合、ユーザーのパスワード、役割に関する情報も持つオブジェクトをビューレイヤーに与える必要はありません (または与えたくありません)。身長やミドルネームなど、あまり敏感ではない可能性があるいくつかのプロパティを取ります)。代わりに、名、姓、ユーザー名、および画像のプロパティを持つオブジェクトをビューに与え、ビューはデータの表示方法のみを決定します。そうすれば、どのデータを表示するかの決定は、コントローラー レイヤーにとどまることが確実になります。
理由 2: ORM ツールの追跡機能に関する問題を回避する
一部の ORM ツールは (通常のオブジェクトを返すものでも1 )、非常に高度な方法を使用して、データ層から取得したオブジェクトの変更を追跡し、レコードの変更を容易にします。たとえば、データ ストアからオブジェクトを取得し、そのインスタンスのいくつかのプロパティを変更してから、save()
メソッドを別の場所に配置すると、オブジェクトがデータベースで更新されます。ORM ツールによっては、ORM エンティティをビュー レイヤーに転送すると、パフォーマンスの問題 (最悪の場合: データベース接続が開いたままになる) から望ましくない影響 (たとえば、ビュー レイヤーのバグがデータ ストア)。これらを回避するには、エンティティをアプリケーション パイプラインの奥深くに送信する前に、ORM ツールとは関係のない「真の通常のオブジェクト」に再マップします。ビュー モデルは、この目標を達成するための (多くの) 方法の 1 つです。
これが必要かどうかは、ORM ツールに完全に依存することに注意してください。Entity Framework の内部動作については、気にする必要があるかどうかを知るのに十分なほどよくわかりませんが、(非常に) 初期の EF では、少なくとも Code-First アプローチを使用していない場合は、これが問題でした。
結論:気にする必要はありますか?
いいえ、必ずしもそうではありません。ビュー モデルがなくても問題なく動作する可能性があります。その場合、ビュー モデルは単なる別の抽象化レイヤーであり、アプリケーションに複雑さ以外の何も追加しません。それはすべて、ORM ツールがコードに何らかの要件を課すかどうか、およびあなたが「MVC 純粋主義者」であるかどうかにかかっています。
補足: しかし、大量割り当ての脆弱性についてはどうでしょうか?
Queti-Mportaは、大量割り当ての脆弱性が問題になる可能性があることをすでに指摘しています。これが深刻な問題であることには同意しますが、ビュー モデルを使用して解決することに同意しません。
私にとって、ビューモデルはコントローラーからビューへのデータ転送オブジェクトであり、コントローラーが表示する必要のあるデータを整理して要約するのに役立ちます。大量割り当ての脆弱性などの問題を回避するために、私は通常、ビュー モデルに非常に似ている編集モデルを使用しますが、反対方向、つまりコントローラーに対してです。誰もがこの区別をしているわけではありません。しかし、この語彙を使用すると、ユーザーにデータの変更を許可する場合は常に編集モデルを使用し、役立つ場合にのみビューモデルを使用することをお勧めします。
1 .NET では通常、「POCO」または Plain Old CLR Objects と呼ばれます。Java は POJO (Plain Old Java Objects) で同等であり、オブジェクト指向プログラミングで使用できる言語を考えることができれば、その言語も同等です。