本を読んでそれが言うことを実行するほど明確ではありません。あなたは考えて、あなたの特定の状況に知識を適用する必要があります。
これは、クラス内の変数をどのように初期化し、オブジェクト構築の直後にそれらを使用するかによって異なります。
いくつかのポインタ:
例:
オブジェクトにサラリーキャップがあるとします。
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パラメーターなど)を信頼しない場合は、それらを検証し、場合によっては、さらにコードを実行する前に入力をサニタイズする必要があります。これにより、セキュリティ攻撃が防止されます。
コンストラクターで検証とパラメーターチェックを行うのはいつもうんざりです。入力を検証するためにゲッターとセッターが必要です。そうすれば、オブジェクトの作成時に何かが発生した場合でも、状態を簡単に判断できない完全に一貫性のないオブジェクトよりも、少なくとも半動作するオブジェクトが保証されます。もちろん、これはコンテキストによって異なります。制約が厳しい場合は、オブジェクトの作成を停止して、クライアント(ユーザー、呼び出し元オブジェクトなど)に有効な入力パラメーターの入力を求めることができます。
getters / settersを使用することで得られる利点は、作成中に検証を制約する以外に、オブジェクトが提供する外部インターフェイスを呼び出すことによってオブジェクトが実際に段階的に構築されることです。これにより、例外が発生すると、オブジェクトが使用不可/不安定になります。
したがって、これの代わりに:
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;
}
}
後者を使用すると、呼び出し元に対して有効な例外を指定して正常に終了することができます。これは、オブジェクトの作成には影響しません(コンストラクターで例外をスローするのは好きではありません)。
一言で言えば、変数には制約がありますか?はいの場合、内部データプロパティに設定する前に、これらの制約を検証します。