ビューは検証を実行すべきではありませんか?


10

MVCでモデルが検証を処理する必要がありますか?」と読んでいたのは、検証ロジックがMVC Webサイトのどこにあるのか知りたいからです。上位回答の1行は次のようになります。「コントローラーは検証を処理し、モデルは検証を処理する必要があります。」

私はそれが好きでしたが、なぜビューでデータ検証を行わないのか、いくつかの理由で疑問に思いました。

  1. ビューは通常、堅牢な検証サポート(JSライブラリ、HTML5タグ)を備えています
  2. ビューはローカルで検証できるため、ネットワークIOを削減できます
  3. UIはすでにデータタイプ(日付のカレンダー、数値のスピナー)を考慮して設計されているため、検証から1つの小さなステップになっています

複数の場所で検証することは、責任を分離するというMVCの概念に反するため、「両方で実行する」ことは不適切に思われます。コントローラでのみデータ検証を行うことは、本当に主要なアプローチですか?


ここでの問題は誤った二分法の1つである可能性があります。複数の場所で検証を実行できない理由はありません。また、「どちらか一方」または「どちらでもない」として状況を考えると、この質問の見方がぼやけます(しゃれます)。 。たとえば、Webサイトでクライアント側の検証を行うと、ユーザーはすぐにフィードバックを受け取ることができるので非常に便利ですが、信頼性が低く、唯一の検証ではありません。
Miles Rout

回答:


10

すべての検証を行う必要があると言える場所は1つだけではないと思います。これは、標準のasp.net mvc Webサイトでいくつかの異なるプログラミング戦略が一緒に機能しているためです。

まず、ドメインロジックをモデルに、「アクション」ロジックをコントローラーに、表示をビューに分離するという考えがあります。これは、ブラウザがビューのレンダリングを提供するだけでサーバー上ですべてのロジックが実行されるという考えに基づいています。

次に、クライアント側のJavaScriptを使用してビューを拡張します。これは最近非常に進んでいるため、Jquery / knockout / angularを使用した「1ページのWebサイト」という考え方が一般的です。

この方法は、それ自体がMVCまたはMVVMパターンを実装するクライアント側アプリケーション全体を作成することと同じです。ビューをデータ転送オブジェクトに、コントローラーをサービスエンドポイントに変更します。すべてのビジネスロジックとUIロジックをクライアントに移動します。

これによりユーザーエクスペリエンスが向上しますが、本質的に信頼できないクライアントを信頼する必要があります。したがって、クライアントがリクエストを事前に検証する方法に関係なく、サーバーで検証ロジックを実行する必要があります。

また、多くの場合、クライアントが実行できない検証要件があります。例えば。「私の新しいIDは一意ですか?」

最高のエクスペリエンス/パフォーマンスを提供することを目的として作成したアプリケーションは、必ず複数のプログラミングパラダイムを借用し、妥協してその目標を達成します。


4
+1および強調:クライアントが投稿したデータを信頼しないでください。ずっと。
マチャド

私の見方:「検証は独立した概念ではありません。アプリケーションのすべての部分を異なるコンテキストで相互に検証する必要があります。」仕事が増えても意味があります。
WannabeCoder 2015年

はい。ただし、「2つ(またはそれ以上)のアプリがあり、すべて異なるパターンに従う」
Ewan

" den・i・grate:不当に批判する;敬意を表する。 "私はあなたがその言葉を正しく使っているとは思わない。そうでなければ、良い答えです。
kdbanman 2015年

いいえ、それが私が意味したことです
Ewan

1

複数の場所で検証することは、責任を分離するというMVCの概念に反するため、「両方で実行する」ことは不適切に思われます。

ここで検討すべき検証の責任は複数あるのでしょうか?#3で言ったように:

UIはすでにデータタイプ(日付のカレンダー、数値のスピナー)を考慮して設計されているため、検証から1つの小さなステップになっています

だから多分それは:

表示:入力タイプ、形式、要件を検証します...ビジネスロジックとは何の関係もない基本的なユーザー入力の検証。サーバーのリクエストを作成してネットワークトラフィックを生成する前に、これらすべてのフワフワしたものをキャッチします。

モデル:データのビジネス上の懸念を検証します。ビジネスルールによると、それは合法的な値ですか?はい、それは数値です(ビューで確認しました)が、意味がありますか?

ちょっとした考え。


1

永続化のための検証が必要だと仮定します。

ビューだけでなく、モデルも検証を処理するべきではありません。ITでの日々の中で、DDDは実際に正しく作業を行っていることを確認する方法の1つであることに気付きました。クラスは実際にそれらがどうあるべきかについて責任があります。

ドメイン駆動設計に従う場合、モデルにはビジネスロジックが含まれますが、それだけです。しかし、検証は含まれていません。なぜでしょうか。

ドメインレイヤーを永続化するのData Mapperではなく、すでに使用していると仮定しますActive Record。ただし、それでもモデルを検証する必要があるため、モデルに検証を追加します。

interface Validation
{
    public function validate();
}

class ConcreteModel extends MyModel implements Validation
{
    public function validate() { // the validation logic goes here }
}

検証ロジックにより、モデルをMySQLデータベースに正しく挿入できるようになります...数か月後、モデルを、MySQLとは異なる検証ルールを必要とするnoSQLデータベースにも保存したいとします。

しかし、問題がありModelます。検証方法は1つしかありませんが、2つの異なる方法で検証する必要があります。

モデルは、彼らが責任を負うことを実行する必要があり、ビジネスロジックを処理して適切に実行する必要があります。検証はビジネスロジックではなく永続性に関連付けられているため、検証はモデルに属しません

Validator代わりにを作成する必要があります。これは、コンストラクターで検証するモデルをパラメーターとして取り、Validationインターフェイスを実装し、これらValidatorのを使用してオブジェクトを検証します。

interface Validation
{
    public function validate();
}

class MySQLConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model here
    }
}

class RedisConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model with different set of rules here
    }
}

将来いつでも別の永続化レイヤーに別の検証メソッドを追加したい場合(RedisとMySQLはもう進む方法ではないと判断したため)、別のものValidatorを作成し、IoCコンテナーを使用して適切なインスタンスベースを取得しますあなたのconfig


1

多くの開発者にとって、愚かな醜いコントローラーに対するファットモデルは好ましい方法です。

本文の基本概念は

...したがって、モデルは単なるデータベースではないことを常に覚えておいてください。Webサービスから取得したデータでさえ、モデルとして表現できます!はい、Atomフィードもです!モデルの紹介を揺るがすフレームワークは、誤解をさらに悪化させるだけのこの前払いをほとんど説明しません。

そして

ユーザーがモデルに意図を伝えることができるように、ビューはUIの生成と表示のみに関係する必要があります。コントローラは、UI入力をモデルのアクションに変換し、ビューがモデルの存在を認識しているビューからの出力を返すオーケストレータです。コントローラは、ユーザー入力をモデルの呼び出しにマップするという意味でのみアプリケーションの動作を定義する必要がありますが、その役割を超えて、他のすべてのアプリケーションロジックがモデル内に含まれていることを明確にする必要があります。コントローラーは、最小限のコードを備えた、低レベルの生き物であり、ステージを設定して、物事が組織的に機能するようにします。

ユーザーがモデルに意図を伝えることができるように、ビューはUIの生成と表示のみに関係する必要があります。これは重要な部分です。モデルは格納されたデータを定義する必要があるため、データの有効性をチェックする責任も負う必要があります。

個人の記録を取る場合、各個人は国によって与えられた一意のID番号を持っている必要があります。このチェックは(通常)UNIQUEデータベースによるキーチェックによって行われます。各ID番号は、いくつかの制御ステップを満たしている必要があります(奇数桁の合計は偶数桁の合計と等しい必要があります)。このタイプの制御は、Model

コントローラはからデータを収集しModelてに渡すViewか、逆に、ユーザーデータを収集してViewに渡しModelます。データへのアクセスとその検証の制限は、によって行われるべきではありませんController。それはだったControllerCookieデータを収集し、それが誰Modelそれが有効なセッションであるか、ユーザがアプリケーションのこの部分へのアクセス権を持っている場合はこれをチェックします。

Viewユーザーからデータを収集するか、ユーザーにデータを提示するユーザーインターフェイスです。簡単なチェックはView、ユーザーが電子メールアドレスを入力したかどうかで行うことができます(したがって、ビューでも行うことができます)IMO。

ビューはクライアント側であり、ユーザー入力を押し込むべきではありません。JavaScriptはクライアント側で実行できない可能性があります。ユーザーは手書きのスクリプトを使用してそれらを変更したり、ブラウザを使用してスクリプトを無効にしたりできます。クライアント側の検証スクリプトを設定できますが、決してそれらを押し込んでレイヤーを実際にチェックしないでくださいModel


強調しておきますが、UIのみに関係するビューは、何らかの形の検証を実行できないことを意味しません。ユーザーがミスをしたときに即座にフィードバックを提供することは、クライアント側のスクリプトが実際に重要である理由ですWebサイトに適用されるMVCのコンテキストで役立ちます。
Miles Rout

@MilesRoutは実際にはSimple checks can be done by the View like the user input e-mail address or not 多分それは明確ではないことを意味します。しかし、あなたが言ったことは私にも当てはまります。シンプルで簡単なチェックは、ビューで簡単に行うことができます。
FallenAngel

私はあなたに反対していませんでした。
Miles Rout 2015年

0

ビューはffの目的で検証を実行する必要があります。

  1. )フロントエンドの検証により、サーバーのデータトラフィックを削減できます。
  2. )サーバー内を移動する前に無効なデータを処理します。
  3. )より高いセキュリティが必要な場合は、フロントエンドとバックエンドの検証の組み合わせの方が適しています。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.