「クラスのクライアントがその不変条件を破壊するために全力を尽くすことを想定して、防御的にプログラムする必要があります。」
安全な言語としての Java:
- Java は C/C++ で一般的なメモリ エラーを防ぎますが、クラスを他のクラスとの望ましくない相互作用から完全に分離することはできません。
- クラスのクライアントがその不変条件に違反しようとする可能性があることを想定して、防御的なプログラミングが必要です。
不変クラスとセキュリティ:
- 不変のように見えるクラス「Period」の例ですが、Date などのオブジェクトの変更可能性により破損する可能性があります。
- 解決策: コンストラクターで可変パラメーターを受け取るときに、そのパラメーターの防御的なコピーを作成します。
public Period(Date start, Date end) {
this.start = new Date(start.getTime()); // Cópia defensiva
this.end = new Date(end.getTime());
if (this.start.compareTo(this.end) > 0)
throw new IllegalArgumentException(start + " after " + end);
}
ビルダーの防御コピー:
- 脆弱性 (TOCTOU 攻撃など) を回避するには、パラメーターを検証する前に防御用のコピーを作成する必要があります。
- 信頼できない可能性のあるオブジェクトの防御コピーには clone() の使用を避け、静的コンストラクターまたはファクトリ メソッドを優先します。
ゲッターと可変性:
- 問題: ゲッターは変更可能な内部コンポーネントを公開し、外部の変更を許可する可能性があります。
- 解決策: ゲッターは可変オブジェクトの防御コピーを返す必要があります。
public Date getStart() {
return new Date(start.getTime()); // Cópia defensiva
}
可変クラスへのアプリケーション:
- 防御的コピーは、クライアントが提供する可変オブジェクトへの参照を保存する可変クラスにも適用されます。
- 例: オブジェクトを Set または Map に保存するときは、そのオブジェクトを後で変更できるかどうかを考慮する必要があります。
内部コンポーネントの返品:
- 変更可能な内部を返すときは、防御的なコピーまたは不変のビューを返すことを検討してください。
不変オブジェクトの使用:
- 可能な限り、防御的なコピーの必要性を避けるために、不変オブジェクトを内部コンポーネントとして使用してください。
費用と代替案:
- 防御用コピーはパフォーマンスに影響を与える可能性があります。代替案には、ドキュメントや明確な使用契約に依存することが含まれます。
- デザイン パターン (ラッパーなど) など、明示的な制御の譲渡の場合、防御的なコピーを省略できます。
結論:
- コストが非現実的である場合、または相互信頼が確立され、明確な文書化が必要な場合を除き、クラスの整合性を保護するために防御コピーを使用します。
本の例:
以上が項目 必要に応じて防御用コピーを作成するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。