18

最近では、大学での OS プログラミング コースから習慣を得て以来、すべての関数のすべての前提条件をチェックすることに慣れています。

一方、ソフトウェア工学コースでは、共通の前提条件は 1 回だけチェックするように教えられました。たとえば、関数が別の関数に委譲されている場合、最初の関数はそれらをチェックし、2 つ目の関数では再度チェックする必要があります。冗長です。

冗長な点は確かにわかりますが、常にチェックする方が安全だと思います。さらに、以前にチェックした場所を追跡する必要はありません。

ここでのベストプラクティスは何ですか?

4

9 に答える 9

11

前提条件をチェックする方法に関する「厳密で迅速な」ルールは見たことがありませんが、通常はメソッドのドキュメントのように扱います。公開されている場合、前提条件が満たされていると断言します。この背後にある論理は、範囲がより広い規模でより少ない影響で消費を期待していることを示しているということです.

個人的には、プライベート メソッドの周りにアサーションを配置する努力は、基本的に重要なタスクを実行するか、外部のコンプライアンス要件の対象となるか、またはエラーが発生した場合に回復できない、「ミッション クリティカルな」メソッドのために取っておくものです。例外。これらは主に「判断の呼びかけ」です。

節約された時間は、徹底的なユニットおよび統合テストの強化に再投資して、これらの問題を洗い流し、入力アサーションの品質を強化するのに役立つツールを配置することができます。あなたのコントロールかどうか。

于 2010-05-28T11:25:42.500 に答える
5

チームがどのように編成されているかによると思います。チーム外からの入力を確認してください。

  • エンドユーザーからの入力を確認する
  • 他のチームによって作成されたソフトウェア コンポーネントからの入力を確認する
  • 独自のコンポーネント内または独自のチーム内から受け取った入力を信頼します。

これは、サポートとメンテナンス (つまりバグ修正) のためです。バグ レポートがある場合、どのコンポーネントに問題があるか、つまりどのチームにバグを割り当てるかをできるだけ早く知りたいと考えています。

于 2010-05-28T11:30:30.507 に答える
4

関数が別の関数に委任している場合、最初の関数はそれらをチェックする必要がありますが、2番目の関数でそれらを再度チェックすることは冗長です。

これらの関数が相互に呼び出す方法を変更するとどうなりますか?または、最初の関数が委任する2番目の関数に新しい検証要件を導入しますか?常にチェックする方が安全だと思います。

于 2010-05-28T11:32:23.560 に答える
4

私は、(コメントで指摘されているように) 呼び出しが外側から来るか (チェックされていない例外、発生する可能性がある)、または内側から来るか (アサート、発生しないはず) に応じて、前提条件のチェックアサートを区別する習慣をつけました。)。

理想的には、運用システムにはアサートのペナルティがなく、Design By Contract(TM) のようなメカニズムを使用してアサーションを静的に排出することもできます。

于 2010-08-07T07:23:43.257 に答える
3

私の経験では、カプセル化に依存します。内部関数がプライベートである場合、その前提条件が設定されていることを確信できます。

それはすべてデメテルの法則についてだと思います、あなたの友人とだけ話してください。

ベスト プラクティスの基礎として、呼び出しが公開されている場合は、入力内容を確認する必要があります。

于 2010-05-28T11:23:27.967 に答える
2

ベストプラクティスは、いつか失敗する場合にのみこれらのチェックを行うことだと思います。次の場合に役立ちます。

デバッグ

単一のメンテナを持つ 1 つのモジュール内の複数のプライベート関数がデータを交換する場合、それらをチェックする意味はありません。もちろん、特に言語に静的型システムがない場合や、データが「文字列型」である場合は例外があります。

しかし、公開 API を公開すると、ある日、誰かがあなたの前提条件を破ることになります。呼び出し元のモジュールを保守する担当者が (組織構造および物理的な場所で) 離れているほど、発生する可能性が高くなります。そして、それが発生した場合、事前条件の失敗の明確なステートメントと、それが発生した場所の仕様により、デバッグの時間を節約できます。 漏れやすい抽象化の法則は今でも真実です...

QA

前提条件の失敗は、QA がテストをデバッグするのに役立ちます。モジュールの単体テストによってモジュールが前提条件の失敗を引き起こした場合、それはコードではなく、テストが正しくないことを意味します。(または、前提条件のチェックが間違っているが、その可能性は低い)。

QA を実行する手段の 1 つが静的分析である場合、前提条件チェックに特定の表記法がある場合 (たとえば、これらのチェックのみがassert_preconditionマクロを使用する場合) も役立ちます。静的解析では、誤った入力とソース コードのエラーを区別することが非常に重要です。

ドキュメンテーション

ドキュメントを作成する時間があまりない場合は、コードに付属のテキストを補助させることができます。明確で目に見える前提条件チェックは、実装の残りの部分とは別に認識され、可能な入力をある程度「文書化」します。(この方法でコードを文書化する別の方法は、単体テストを作成することです)。

于 2010-05-28T11:38:06.713 に答える
2

すべての場合と同様に、要件を評価して、それぞれの状況に最適なソリューションを見つけてください。

前提条件の確認が簡単な場合 (「ポインターが null ではない」) は、頻繁に確認することもできます。チェックが難しい (「有効な null で終わる文字列を指している」) か、時間、メモリ、またはその他のリソースが高価な前提条件は、別の方法で処理される場合があります。パレートの法則を利用して、簡単に達成できる成果を上げましょう。

// C, C++:
void example(char const* s) {
  // precondition: s points to a valid null-terminated string
  assert(s); // tests that s is non-null, which is required for it to point to
  // a valid null-terminated string.  the real test is nearly impossible from
  // within this function
}

前提条件の保証は、呼び出し元の責任です。このため、いくつかの言語では、オプションでスキップできる「アサート」構造を提供しています (たとえば、C/C++ の NDEBUG の定義、Python のコマンドライン スイッチの定義)。これにより、最終的なパフォーマンスに影響を与えることなく、特別なビルドで前提条件をより広範囲にテストできます。ただし、assert の使用方法については議論が白熱する可能性があります。ここでも、要件を把握し、一貫性を保つ必要があります。

于 2010-05-28T14:09:30.097 に答える
0

ベスト プラクティスは、常にチェックすることです。

于 2010-05-28T11:23:55.530 に答える