web-dev-qa-db-ja.com

複数の条件をチェックする方法は?

複数の条件を特定の順序で確認するためのベストプラクティスは何ですか?

問題の例では、4つの異なる条件を任意の順序でチェックし、正しいエラーメッセージの表示に失敗する必要があります。

以下の例では、Cのような構文を使用しています。

オプション1:すべてを一度に確認する

この方法は、条件が失敗した理由を簡単に識別できないため、推奨されません。

if (A && B && C && D) {
    // continue here...
} else {
    return "A, B, C, or D failed";
}

オプション2:ネストされた条件

以前は、ネストされた条件ステートメントを使っていました。これは本当に混乱する可能性があります。

if (A) {
    if (B) {
        if (C) {
            if (D) {
                // continue here...
            } else {
                return "D failed"
            }
        } else {
            return "C failed";
        }
    } else {
        return "B failed";
    }
} else {
    return "A failed";
}

オプション3:早期失敗

これは私が使用する現在の方法で、fail-earlyを呼び出します。 「悪い」状態になるとすぐに戻ります。

if (!A) {
    return "A failed";
}

if (!B) {
    return "B failed";
}

if (!B) {
    return "C failed";
}

if (!D) {
    return "D failed";
}

// continue here...

オプション4:エラーを収集する

私が考えることができる最後のアプローチの1つは、一種のcollectionエラーです。テストする条件が完全に異なる場合、このアプローチを使用することをお勧めします。

String errors = "";
if (!A) {
     errors += "A failed\n";
}

if (!B) {
    errors += "B failed\n";
}

if (!C) {
    errors += "C failed\n";
}

if (!D) {
    errors += "D failed\n";
}

if (errors.isEmpty()) {
    // continue here...
} else {
    return errors;
}

複数の条件をチェックするためのベストプラクティスは何ですか?期待に関しては、理想的にはすべての失敗の詳細が返される例4のように動作します。

30
Redandwhite

答えは...場合によります。

A、B、C、またはDのいずれかが機能しないのですか? Aをチェックして失敗すると、B、C、またはDをチェックすることが非現実的または冗長になりますか?報告されたエラーのコレクション、または最初に検出されたエラーだけを報告することは役に立ちますか?

提示された各オプションは、適切な状況で使用されます。それらすべてを支配するための単一のエラー処理アプローチはありません。

21
user40980

これは、関数からどのような情報を取得するかによって異なります。すべてのオプションがあなたに与えるものを分解しましょう:

  1. どの条件が失敗するかは気にせず、すべてが成功するかどうかを知りたいだけです。

  2. 明らかに邪魔にならない。コードの入れ子のため、非常に悪いフォーマットと可読性。 #3と同じことをしますが、醜いです。

  3. 失敗した最初の状態を知ることができます。

  4. 失敗したすべての状態を知ることができます。

コンテキストと実際に必要な情報に応じて、どのオプションが最適かを判断するのは実際にあなた次第です。

15
marco-fiset

答えは、使用している言語と、エラーの結果として何をするかによって大きく異なります。

たとえば、Scalaでは、すべてのエラーを報告して一度にすべて修正できるようにする場合、おそらく次のようにします

_val (yes, no) = List(
  (A, "A failed"),
  (B, "B failed"),
  (C, "C failed"),
  (D, "D failed")
).partition(_._1)
if (!no.isEmpty) Some(no.map(_._2)) else None
_

ここで、最初に条件とエラーメッセージをグループ化し、次にそれらを2つのグループ(成功と失敗)に分類し、何かがあった場合はそれらのエラーメッセージを返し、そうでない場合は-この場合は-すべて大丈夫です。

しかし、これは、コレクションとコンテナーをすばやくグループ化してマップし、操作するScalaの機能に大きく依存しています。 Javaでは、まったく同じコードをより詳細に記述します(また、何かに失敗したかどうかを知るためにerrors.size()をクエリする必要があるため、チェックするのが不便です)。

_ArrayList<String> errors = new ArrayList<String>();
if (!A) errors.add("A failed");
if (!B) errors.add("B failed");
if (!C) errors.add("C failed");
if (!D) errors.add("D failed");
return errors;
_

最初のエラーだけが必要な場合は、Javaで失敗しますが、Scala

_List(A,B,C,D).zipWithIndex.find(!_._1).foreach{ x => return x._2 }
_

不良になったアイテムの数をリターンコードとして問題ないとしました。

したがって、答えは本当に重要です。重要なさまざまなスタイルがありますが、最も効率的/最も苦痛にそれらを実装する方法は、ツールに大きく依存します。

3
Rex Kerr