MVCパターンに従ってWebアプリケーションを作成しています。
事実上Java作者は、新しいオブジェクトを作成するときにクラスのコンストラクターのパラメーターを検証することに言及しています。
ただし、サードパーティが使用するAPIは作成していません。私のクラスは、サーバーに送信される前に検証されるフォームの入力フィールドからパラメーターを受け入れるだけです。
したがって、この場合、著者がEffective Java)で言及している方法でクラスを作成する必要がありますか、それとも役に立たないのでしょうか。
それは本を読んでそれが言うことを実行するほど明確ではありません。あなたは考えて、あなたの特定の状況に知識を適用する必要があります。
これは、クラス内の変数をどのように初期化し、オブジェクト構築の直後にそれらを使用するかによって異なります。
いくつかの指針:
変数がクラス内の一部のメソッドで使用される場合、またはオブジェクトが構築の直後に再利用される場合(ほとんどの場合)、必要な値が空またはnullでないことを検証する必要があります。厄介な例外を回避するため。
入力パラメーターを検証する2回目は、正しい値が特定の内部変数に設定されることを期待する場合です。パラメータを特定の値の範囲に制限する必要がある場合は、検証することが重要です。
例:
オブジェクトにサラリーキャップがあるとします。
int salary = 0;
int salaryCap = 1000;
作成時に、渡された給与額を検証できます。
public Employee(int salary) {
if(salary >= this.salaryCap)
this.salary = salary;
}
例:
スーパーコンストラクターを呼び出さなければならないときはいつでも、入力を検証したくなります。
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;
}
}
後者を使用すると、呼び出し元に対して有効な例外を指定して正常に終了することができます。これは、オブジェクトの作成には影響しません(コンストラクターで例外をスローするのは好きではありません)。
一言で言えば、変数には制約がありますか?はいの場合、内部データプロパティに設定する前に、これらの制約を検証します。
ドメイン内のデータを検証し、フィールドが正しく入力されていない場合は(カスタム)例外を返すことをお勧めします。このようにして、検証プロセス全体を再度実行することなく、別のUIを実装できるようになります。これは、可能な限り分離するのが最善です。
検証は以前に行われたため、一見したところ、パラメーターを検証する必要はありません。ただし、クラスが他の状況で使用されることを考慮に入れる必要があります。コンストラクターの入力が常に有効であるかどうかを確認することはできません。