すべてのコンストラクタでデータの妥当性をチェックしますか、またはデータが正しいと仮定して、パラメータに問題がある特定の関数で例外をスローしますか?コンストラクタ内の間違ったパラメータ値をチェックする必要がありますか?
答えて
コンストラクタも関数です - なぜ区別するのですか?
オブジェクトを作成すると、すべての整合性チェックが完了したことを意味します。コンストラクタ内のパラメータをチェックし、不正な値が検出されたら例外をスローするのは完全に合理的です。
このうち、デバッグが簡単になります。あなたのプログラムがコンストラクタ内で例外をスローすると、スタックトレースを見ることができ、しばしば原因をすぐに見ることができます。チェックを遅らせると、以前のイベントが現在のエラーを引き起こす原因を検出するために、より多くの調査を行う必要があります。
すべての不変条件が最初から満たされている完全に構成されたオブジェクトを持つ方が常に良いです。ただし、管理されていない言語でコンストラクタから例外をスローすると、メモリリークが発生する可能性があります。
コンストラクタをスローすると、間違った値がどこから来ているのかがスタックトレースによって示される可能性が高くなります。
私は一般的なケースではsharptoothに同意しますが、一部の機能が有効であり、一部が有効でない状態を持つことができるオブジェクトがあることがあります。このような状況では、これらの特定の依存関係を持つ関数にチェックを延期する方がよいでしょう。
通常は、オブジェクトが常に有効な状態にあるという理由だけで、コンストラクタで検証する必要があります。しかし、いくつかの種類のオブジェクトには機能固有のチェックが必要ですが、それも問題ありません。
私は常にコンストラクタで値を強制します。ユーザーがルールに従わなくても困らない場合は、私はそのことを知らずに黙って実行します。
したがって、107%の値を渡すと100%に設定されます。ドキュメントでは、それが起こるのは明らかです。
明白な論理強制がない場合に限り、私はそれらに例外を戻します。私はこれを「ドキュメントを読むにはあまりにも怠け者や愚かな人たちに、最も驚くべき校長」と呼ぶのが好きです。
これは難しい質問です。この質問に関連する私の習慣はここ数年で変わりましたので、ここにいくつかの考えがあります:
- 伝統的な方法の引数をチェックするのと同じです...私はここで区別しません...
- もちろん、メソッドの引数をチェックすることは、渡されたパラメータが正しいことを確認するのに役立ちますが、あなたが書かなければならない多くのコードを導入します。 ...特に、他のメソッドにかなり頻繁に委譲する短いメソッドを書くときは、コードチェックの50%で終わると思います。
- その他あなたがクラスの単体テストを書くとき、非常に頻繁に考えると、すべてのメソッドに対して有効なパラメータを渡す必要はありません...現行のテストケースで重要なパラメータだけを渡すのが理にかなっていますチェックをすることでユニットテストを書いても遅くなります...
私はこれが本当に状況に依存すると思います...私が最後にしたのは、パラメータが外部システム(ユーザ入力、データベース、Webサービスなど)から来ていることがわかったときだけ、パラメータチェックを書くことです。データが自分のシステムから来た場合、私はほとんどの時間テストを書いていません。
第3のポイントについて:決して起こらないものをテストするのはなぜですか?コンストラクタのパラメータをチェックすると、値は決して間違った値になることはありません。だからあなたはそこでテストする必要はありません。間違ったパラメータでコンストラクタをテストするだけです。 –
理論的には、関数を呼び出す前に、呼び出し元コードは常に前提条件が満たされていることを確認する必要があります。コンストラクタも同じです。
実際には、プログラマは怠惰であり、前提条件を確認するのが最善です。アサーションはそこに便利です。
例。
// precondition b<>0
function divide(a,b:double):double;
begin
assert(b<>0); // in case of a programming error.
result := a/b;
end;
// calling code should be:
if foo<>0 then
bar := divide(1,0)
else
// do whatever you need to do when foo equals 0
また、前提条件はいつでも変更できます。コンストラクタの場合、これは本当に便利ではありません。
// no preconditions.. still need to check the result
function divide(a,b:double; out hasResult:boolean):double;
begin
hasResult := b<>0;
if not hasResult then
Exit;
result := a/b;
end;
// calling code:
bar := divide(1,0,result);
if not result then
// do whatever you need to do when the division failed
これはちょうど括弧のないCだけではありません。それはパスカルです!彼はパスカルのコンパイラを持っています。あなたの人生のために実行します。 – paxdiablo
できるだけ早く必ず失敗してください。このプラクティスの良い例は、実行時に表示されます。 *配列に無効なインデックスを使用しようとすると、例外が発生します。 *後で実行しようとしないとすぐにキャスティングが失敗します。
悪いキャストがリファレンスに残っていて、例外を使用しようとするたびに災害コードが何であるか想像してみてください。賢明なアプローチは、できるだけ早く失敗し、悪い/無効な状態をできるだけ早く回避することです。
- 1. コンストラクタのパラメータを検証する必要がありますか?
- 2. コンストラクタはパラメータを指定する必要があります
- 3. PHPアプリケーションが間違ったデータベース値でエラー処理を実行する必要がありますか?
- 4. モデル内のパラメータを更新する必要があります
- 5. コンストラクタ内のすべてを初期化する必要がありますか?
- 6. keyCodeの検出に間違った値があります
- 7. Resourcemanagersのリソースセットに間違った値があります
- 8. 移動コンストラクタはnoexceptである必要がありますか?
- 9. ThreadLocal - コンストラクタで値を設定する必要がありますか?
- 10. GLSL Frag Shaderに間違った値があります
- 11. symfony 1.4 app.ymlに間違った値があります
- 12. onClickListenerで間違った変数値があります
- 13. date_diffに間違った違いがありますか?
- 14. 400で間違った要求がありました
- 15. QLineEditsをコンストラクタまたはメソッドで作成する必要がありますか?
- 16. オブジェクトリテラルまたはコンストラクタ関数を使用する必要がありますか?
- 17. REST:間違った状態のリソース - どのHTTPステータスを返す必要がありますか?
- 18. 「シリアルポート」を必要とする間違った宝石が必要です
- 19. javaを使用してリスト内のオブジェクトのパラメータをチェックする必要があります(リストに重複する値もあります)
- 20. C#でラジオボタンをチェックする必要がありますか?
- 21. CollectionChangedイベントでNotifyCollectionChangedActionをチェックする必要がありますか?
- 22. EntityコンストラクタにDbContextを渡す必要がありますか?
- 23. Pl/sqlはINパラメータを ''の間に入れる必要がありますか?
- 24. JPA StoreProcedureQueryがパラメータから始まる間違った値を取得する
- 25. Pythonのプラクティス:コンストラクタのパラメータをチェックする良い方法はありますか?
- 26. 定数またはコンストラクタのメンバを参照または値で渡す必要がありますか?
- 27. angularjs expression値または値と型(===または==)の両方のみチェックする必要があります
- 28. Atmelstudio UC3C AVR32 - フレームワークオブジェクトがメモリ内の間違った場所にありますか?
- 29. 仮想ホストからのguzz要求に間違ったIPがあります
- 30. IL戻り値が間違った値を返します
これは同じです。すべてのメソッドがすべてのオブジェクト状態で合法的に呼び出されるわけではないことは事実です。しかし、コンストラクタにまとめられたパラメータ値の組み合わせを特定し、他の組み合わせがあれば例外をスローすることもできます。 – sharptooth
また、オブジェクトには常に有効なメソッドとそうでないメソッドがある場合、オブジェクトが大きすぎるかどうかを検討することもできます。たぶんそれは分割する必要がありますか? – sleske