2013-03-03 10 views
12

MVCパターンに従ってWebアプリケーションを作成しています。コンストラクタのパラメータを検証する必要がありますか?

有効なJavaでは、新しいオブジェクトを作成するときにクラスのコンストラクタのパラメータを検証することが記載されています。

しかし、私は第三者が使用するいくつかのAPIを作成していません。私のクラスは、サーバーに送信される前に検証されるフォームの入力フィールドからパラメータを受け取ります。

このケースでは、著者が実用的なJavaで言及したようにクラスを作成する必要がありますか、それとも役に立たないのですか?

+0

著者は、コンストラクタ内のパラメータを検証するために記述していることをここでお読みになりましたか? – Kwadz

答えて

9

本を読んで、それを実装するほど明確ではありません。あなたはあなたの特定の状況に知識を考え、適用する必要があります。

それは本当にあなたがあなたのクラスで変数を初期化すると、右のオブジェクトの構築後にそれらを使用している方法によって異なります。

いくつかのポインタ:

  • 変数は、いくつかの方法で使用することを予定している場合オブジェクトが構造の直後に再利用される場合(ほとんどの場合)、不要な例外を避けるために、必要な値が空でもヌルでもないことを検証する必要があります。

  • 入力パラメータを検証する2回目は、特定の内部変数に正しい値を設定すると予想されるときです。パラメータを特定の値の範囲に制限する必要がある場合は、検証することが重要です。

例:

は、私たちがオブジェクトに給料の上限を持って言う:

public Employee(int salary) { 
if(salary >= this.salaryCap) 
    this.salary = salary; 
} 

    int salary = 0; 
    int salaryCap = 1000; 
    

    作成時に、あなたは給与額で渡さを検証することができます

  • また、クラスの関係によって、thを検証するかどうかが決まりますe値であるかどうか。たとえば、継承チェーンのパラメータを継承チェーンに渡す場合、継承チェーン内の他のオブジェクトの状態に影響を与える場合は、それらを検証するために時間がかかります。

例:変数から来ている

public Employee(int salary) { 
super(salary); //validate salary against known constraints 
} 
  • :私はスーパーのコンストラクタを呼び出す必要がありたび

    は、私が検証の入力に誘惑のですか?ソース(SQLパラメータなど)を信頼しない場合は、それらを検証し、さらにコードを実行する前に入力をサニタイズする必要があります。これにより、セキュリティ攻撃が防止されます。

  • 私は常にコンストラクタで検証とパラメータチェックを行うのが疲れています。私は入力を検証するゲッターとセッターを持つことを好みます。そうすれば、オブジェクトの作成時に何かが発生した場合、少なくとも状態が決まらない完全な一貫性のないオブジェクトよりも、半加工オブジェクトの保証があります。もちろん、これはコンテキストによって異なります。制約が厳しい場合は、オブジェクト作成を停止し、クライアント(ユーザー、呼び出しオブジェクトなど)に有効な入力パラメータを要求することができます。

ゲッター/セッターを使用すると、私はオブジェクトが実際のオブジェクトが与える外部インターフェイス上で呼び出すことにより、段階的に構成されていることがあり、例外が発生した作成中に検証を、制約以外のもたらす利点、オブジェクトを使用不能/不安定にします。

だからこれに代えて:

public Employee(int salary) { 
if(salary >= this.salaryCap) 
    this.salary = salary; 
} 

私はこれを好む:

public class Employee { 
public void setSalary(int salary) { 
    if(salary >= this.salaryCap) 
     this.salary = salary; 
} 
} 

を、後者はオブジェクトの作成には影響しませんこれは、私にきれいに呼び出し元に有効な例外で終了することができます(私はコンストラクタで例外を投げるのが好きではありません)。

一言で言えば、変数には制約がありますか?はいの場合は、これらの制約を内部データプロパティに設定する前に検証します。

+10

到着するパラメータが無効な場合、オブジェクトの構築を完了してはいけません。 [IllegalArgumentException](http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/IllegalArgumentException.html)を投げ、壊れたクラス不変式を持つオブジェクトを作成しないでください。あなたの呼び出し元があなたに悪いパラメータを与えている場合は、それらを扱う正しいコンテキストを持つものでなければなりません。おそらくユーザからの新しい入力を収集し、その後にインスタンス化を再試行することを含みます。 – Jazzepi

-4

既に検証済みのフィールドを確認しているようです。 その場合、それはちょうど時間の無駄です(書き込むことと実行することの両方)。あなたのフォーム(クライアントサイドのjavascript)がフィールドを検証していない場合、それは理にかなっています。それ以外の場合はスキップできます。

+4

Trusting * clientside *検証は、あなたができる最悪の事の一つです。 – PeeHaa

+0

はい、それは本当です。だからこそ私はサーバー上でそれらを検証している。 –

+0

あなたがポイントを差し引いている場合は、「それは非常に悪い」だけでなく、理由を説明する必要があります。作成者が購読しているシナリオでは、検証が「複雑」(つまり、この電子メールはすでにデータベースに存在していますか?)のように聞こえません。また、ウェブ以外のAPIがサーバーにアクセスしているようには聞こえません。だから、なぜクライアント側だけを検証するのが「悪い」のだろうか? – ShinySpiderdude

1

前もって検証が行われていたため、パラメータを検証する必要はありません。しかし、あなたのクラスが他の状況で使用されることを考慮に入れるべきです。コンストラクタの入力が有効であることを必ず確かめることはできません。

1

フィールドが正しく入力されていない場合は、ドメイン内のデータを検証し、(カスタム)例外を返すことをお勧めします。このようにして、検証プロセス全体をやり直さなくても別のUIを実装することができます。できるだけこれを分離するのが最善です。

関連する問題