12

アサーティブプログラミングが良い理由が分かったので、JavaScriptで使いたいです。ただし、ユーザーにエラー ボックスを表示したくありません。これは珍しいことです。それを無視して、再試行する方が良いかもしれません。

たとえば、このコードはエラー ボックスを作成し、ユーザーを中断します。

function getDomainFromURL(url) {
    assertTrue(url, 'URL should not be null');

    ...parsing
}

だから、私はこのようにします。

function getDomainFromURL(url) {
    if (!url) return;

    ...parsing
}

2 つ目はユーザビリティに優れており、1 つ目は開発に適していると思います。したがって、IMO では、これらを組み合わせて、assert製品コードで非表示にするのが最善です。

質問 1 そう思いますか。それとも別の考えがありますか?

質問 2 そう思う場合、Spring3 フレームワークでそれを行う良い方法はありますか?

4

6 に答える 6

8

アサートは、いかなる種類のユーザー入力データの検証にも使用しないでください。エラーチェックにも使用しないでください。アサートは、テストが失敗した場合にプログラマーのデバッグを容易にする方法です。また、コードを理解しやすくする方法でもあります。

次の例を検討してください。

function calculateSomeCrazyFormula(a,b,c) {
    var d = a+b+c;
    ....
    k = (x + y)*2;

    assert(k != 0);
    l = d/k;        
    ....
    return x;
}

仕様による私の式は、k が決して 0 にならないことを保証します。ここでは、ほとんどコードのコメントとして assert を使用しました。ロジックを検証するわけではありません。まったく逆です。アサートを使用して、その複雑なロジックの実装が正しいかどうかを検証します。後で自分のコードに戻って、l = d/kk が 0 のときに何が起こるかについて疑いを持たないことがassertわかりました0

また、どこかにエラーがあり、実際に0発生した場合は、通常、より深いエラーが表示されます。例えば:

function otherFormula(a,b,c) {
    var x = calculateSomeCrazyFormula(a,b,c);

    var y = doSomeStuff(x);
    var z = doOtherStuff(y);
    return z;    
}

アサートがないと、この関数の間違った結果が得られます。1 のはずなのに、なぜ 0 を受け取っているのかわからないでしょう。コードを 1 行ずつデバッグし、何が問題なのかを理解する必要があります。

ただし、アサートを使用すると、「アサーションが失敗しました」というエラーにすぐに気付き、問題を探す範囲を即座に最小化できます。

アサートは、Javascript を含むすべてのプログラミング言語で役立ちますが、Live 環境には存在しないはずです。したがって、一部のポストプロセッサ システムでは、リリース前にコードからすべてのアサートを削除する必要があります。

于 2011-07-14T13:23:58.860 に答える
4

2枚目は特に良くないと思います。常に何かを返すことが期待されるメソッドから何も返さない場合、実際の問題がある場所、つまりgetDomainFromURL関数内の近くではなく、コードが別の場所で失敗する可能性があります。

一方、パラメーターが null の場合にこのメソッドが何も返さないことがまったく問題ない場合は、アサーションを追加しても意味がありません。

個人的には、開発と運用の両方で、どこでも最初の形式を使用します。本番環境でアサーションが失敗した場合、問題の原因に関する非常に有用なフィードバック (ブラウザー、ログなど) が得られます。アサーションを削除してもバグは残りますが、追跡が難しくなります。

さておき

このスタイルのプログラミング (前提条件のチェック) は、契約ベースのプログラミングとして知られているものの一部です。「アサーティブ プログラミング」という言葉を聞いたことがありません。

于 2011-07-14T13:06:17.757 に答える
2

いくつかの理由から、Javascript でアサーティブ プログラミングを行うのは良くないと思います。

  1. そのようなエラーチェックを本番環境で行う必要があるという事実は好きではありません。
  2. 人々は、この目的のために特別にユニットテスト フレームワークを開発しました (JsUnit)
  3. この assert ステートメントにより、コード サイズが増加し、ダウンロード時間と実行時間が増加します。

これを行う最善の方法は、単体テストを作成することです。このようにして、更新時にコードが壊れないようにすることができます。また、アサートが本番コードに表示されないことも意味します。if (condition) error();確かに、これらの条件は開発者ではなくユーザーに依存する可能性があるなどのことが必要になる場合があります。これらは避けられず、手動でコーディングする必要があります。

経験則:

  • if (condition) error();条件がユーザーに依存する場合に使用します
  • 条件が開発者に依存する場合は、単体テストを記述します。

最後に、単体テストを使用すると、コードが適切にエラーになるかどうかを確認できます。JsUnitについてはよくわかりませんが、おそらくテストで次のようなことができます:

assertThrow(somefunc, args, YourError);

if (condition) error();あなたのコードであなたと一緒に行く

于 2011-07-14T13:00:13.883 に答える
2

非同期データやユーザー主導のデータを扱うときは、常に条件付きエラー処理が必要です。それは起こります。ユーザーとネットワークが台無しになります。それが人生だ。あなたの最善の策は、データが壊れている可能性があると予想するのが合理的である場合に限り、少なくとも2番目の例を持つことです. テストするデータを提供する責任がある場合は、データが有効であることを事前に確認する必要あります

組み合わせを持たない理由:

function getDomainFromURL(url) {
    if( !assert( url != undefined, 'URL should not be null.' ) ) 
        return ''; 
    // '' is optional, but I don't like returning null if I expect a value.
    /* blah blah blah */
}

// as lightweight a function as you can have.
function assert( val, msg )
{
    if( !val )
    {
        console.log( msg );
        return false;
    }
    return true;
}

よく考えてみれば、私はそのパターンをかなり頻繁に使用しています。

于 2011-07-14T13:08:04.380 に答える
1

次のように使用できます。

function getDomainFromURL(url) {
   assert(url != null, "url is null");
   if (!url) return;
    ...parsing
}

同意しない人もいますが、プリプロセッサを使用するか、難読化ステップがある場合はその一部として、本番コードで assert ステートメントを削除する方法を見つけようとします。これにより、パフォーマンスとコード サイズが向上する可能性がありますが、アサート内から呼び出すコードがプログラムの状態を変更しないようにする必要があります。これも難しいかもしれません。私の結論は、javascript で大規模で堅牢なプログラムを作成するには規律が必要であるということです。

おまけとして、ここにあるアサートを見てください。

http://aymanh.com/9-javascript-tips-you-may-not-know/

于 2012-07-18T10:08:20.967 に答える
1

それを無視して、再試行する方が良いかもしれません。

黙って失敗するのは得策ではありません。使いやすさの観点から、ユーザーは、エラーが発生した場合でも、自分のアクションに関するフィードバックをすぐに受け取る必要があります。コードで何か例外が発生した場合は、単純なエラー ページを表示する必要があります。ここでの考え方は、早く失敗することです

条件が満たされない場合は、アサート関数をエラー ページにリダイレクトし、ログに記録します。XHRwindow.location.hrefを使用して投稿することにより、エラーを設定してログに記録することにより、Javascript でこれを行うことができます。

于 2011-07-14T13:04:58.440 に答える