私は this SOページを読んで、オブジェクトを構築するときにパラメーターをいつチェックするかについてのページを読んでいました。受け入れられた答えは、無効なオブジェクトが建設。
私はそのアプローチに同意し、Person
なしでname
を構築する方法はわかりません。
ただし、 comments のいずれかが推奨されます:
また、2番目のオプションは、1番目のオプションよりも再利用可能であるため、より優れていることに同意します。最初のオプションは、オブジェクト指向の原則に違反しています。ファクトリーメソッドでさえ、それよりもよく設計されています。
質問:
OOPの原則に違反しているのは、コンストラクターで例外をスローしたときですか?コンストラクターが機能してはいけないというガイドラインですか?
OPによって提案された他のアプローチはPersonService
でしたが、これは単なる推測にすぎませんが、このアプローチでは、クライアントコードがpublic void addPerson(Person personToAdd)
を呼び出して人物オブジェクトがnullを含まない?彼らがそのチェックを回避する方法を見つけたらどうなりますか?または、public void addPerson(Person personToAdd)
の前に、有効なPerson
オブジェクトを期待する、自分が記述していない別のクラスでそのオブジェクトを使用しますか?
繰り返しになりますが、これはすべて推測の一部ですが、Person
オブジェクトが作成時に行われたはずのときに有効であることを保証するのは、クライアントに大きな責任を負っているようです。
1)いいえOOP exception をスローすると原理が壊れます- コンストラクタ 。
Bjarne Stroustrupは彼の著書で、IBMやSunのような複数の企業の専門家と協力して、例外が1984年から1989年の間に言語にどのように設計されたかC++の設計と進化を思い出しました:
一部の人にとって、例外の最も重要な側面の1つは、コンストラクターで検出されたエラーを報告するための一般的なメカニズムを提供することです。
これは、Javaおよびその他のOO言語についても同様です。
2)サービスを使用してオブジェクトを作成することも有効な方法です。ビルダーやファクトリを使用してオブジェクトを作成することは珍しくありません。
ファクトリを使用すると、例外をスローするのとは異なる方法でエラーを管理でき、特に、構築前にパラメータの一貫性を制御できます。
ただし、この種のサービスをコンストラクタの上で使用することが常に望ましいとは限りません。
さらに、すべてのエラーを予測することは不可能です。作成中に、パラメーターに関連しない予期しないイベントが発生したとします。たとえば、大きなオブジェクトを作成するのに十分なメモリが残っていない、または一部のリソースがチェックされたが割り当てられなかった(特にRAIIコンテキストで)。
3)それにもかかわらず、例外を悪用しないでください
例外はパラメーター検証の代わりにはなりません。例外に関する最も重要な原則は、例外的な状況でのみ発火することです。悪いパラメーターが一般的な状況である場合、または3つのうちの1つの構造が例外を引き起こす可能性があると予想される場合は、設計に本当に疑問を投げかけ、リスクを減らすためにそれをリファクタリングする必要があります。
名前を事前にチェックする必要があると想定して防御的プログラミングに使用する場合、この例外をセーフティネットとして提供すれば、問題ありません。
オブジェクトをきれいに構築するために現在好まれているパターン(IMO)は Builderパターン です。 Builderの利点の1つは、コンストラクターに渡される前にパラメーターを検証できることです。この検証は、特定のパラメータが設定されている場合、またはbuild()
の呼び出し中に発生する可能性があります。 param()
呼び出しでの検証は Circuit Breaker として機能し、高速に失敗し、使用前に他のパラメーター値を取得する作業を排除する可能性があります。例。
_...size(5).foo(getMassivelyComplexObject()).build
_
_5
_が有効なsize
ではなく、検証がsize()
呼び出しで実装されている場合、foo()
の値を取得するために必要な作業は回避できました。
コンストラクタのシグネチャが変更された場合、ビルダーは次の2つの方法でユーザーを隔離します。
param()
の呼び出しは通常、順序に依存しません。param()
呼び出しはオプションです。Builderパターンには他にも多くの優れた点がありますが、質問は建設中の失敗に関するものなので、ここで終了します。