ネストされた条件式をガードに置き換える方法

 この記事は、HUAWEI CLOUDコミュニティ「ネストされた条件付きをガード句に置き換える」、作成者:JavaEdgeから共有されています。

動機

条件式には通常、次の2つの種類があります。

  • 両方の条件分岐は正常な動作です
  • 1つの条件付き分岐のみが正常な動作であり、もう1つの分岐は異常です

これらの2つのタイプの条件式は、異なる目的を果たします。これは、コードに表示する必要があります。

  • 両方のブランチが正常な動作である場合は、if ...else...という形式の条件式を使用する必要があります

  • 条件が非常にまれな場合は、個別にチェックして、条件が真になったらすぐに関数から返す必要があります

    このような個別のチェックは、「ガード条項」と呼ばれることがよくあります。

ネストされた条件式をガードに置き換えることの本質は、ブランチに特別な注意を払うことです。if-then-else構文を使用する場合は、ifブランチとelseブランチに同じ重みを置きます。このようなコード構造の読者へのメッセージは、各ブランチが等しく重要であるということです。ガードステートメントは、読者に次のように伝えています。「この状況は、この関数のコアロジックが気にするものではありません。発生した場合は、必要なクリーンアップを実行して終了してください。」

「すべての関数は1つのエントリと1つの出口しか持てない」という概念は、一部のプログラマーに深く根付いています。彼らが書いたコードを扱うとき、ネストされた条件式の代わりにガードステートメントを使用する必要があることがよくあります。今日のプログラミング言語では、関数ごとに1つのエントリしか適用されておらず、「単一終了」ルールはそれほど有用ではありません。コードを明確に保つことが重要です。単一の出口で関数が読みやすくなる場合は、単一の出口を使用します。それ以外の場合は、そうではありません。

練習

置き換える必要のある最も外側の条件付きロジックを選択し、ガードステートメントに置き換えます。

テスト。

必要に応じて、上記の手順を繰り返します。

すべてのガードステートメントが同じ結果を生成する場合は、[条件式のマージ]を使用してそれらを組み合わせることができます。

場合

従業員に支払われる賃金を計算します。まだ会社で働いている従業員だけが支払われる必要があるので、この手紙

番号は、2つの「従業員がもう仕事をしていない」状況をチェックする必要があります。

    public Long payAmount(Employee employee) {
        long result;
        if (employee.isSeparated) {
            result = 0;
        } else {
            if (employee.isRetired) {
                result = 0;
            } else {
                // logic to compute amount
                lorem.ipsum(dolor.sitAmet);
                consectetur(adipiscing).elit();
                sed.do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
                ut.enim.ad(minim.veniam);
                result = someFinalComputation();
            }
        } return result;
    }

ネストされた条件付きロジックは、コードが実際に何を意味するのかを理解するのを困難にします。現在の2つの条件式のどちらも真でない場合にのみ、このコードは実際に主な作業を開始します。したがって、ガードステートメントを使用すると、コードでその意図をより明確に表現できます。いつものように、私は小さな一歩を踏み出すのが好きなので、最初に最上位の条件付きロジックを扱います。

    public Long payAmount(Employee employee) {
        long result;
        if (employee.isSeparated) {
            result = 0;
        }
        if (employee.isRetired) {
            result = 0;
        } else { // logic to compute amount
            lorem.ipsum(dolor.sitAmet);
            consectetur(adipiscing).elit();
            sed.do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
            ut.enim.ad(minim.veniam);
            result = someFinalComputation();
        } return result;
    }

この変更を行った後、テストを実行して次のステップに進みます。

    public Long payAmount(Employee employee) {
        long result;
        if (employee.isSeparated) {
            return 0l;
        }
        if (employee.isRetired) {
            return 0l;
        }

        lorem.ipsum(dolor.sitAmet);
        consectetur(adipiscing).elit();
        sed. do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
        ut.enim.ad(minim.veniam);
        result = someFinalComputation();
        return result;
    }

この時点では、結果変数は役に立たないので、削除します。

    public Long payAmount(Employee employee) {
        if (employee.isSeparated) {
            return 0l;
        }
        if (employee.isRetired) {
            return 0l;
        }
        lorem.ipsum(dolor.sitAmet);
        consectetur(adipiscing).elit();
        sed. do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
        ut.enim.ad(minim.veniam);
        return someFinalComputation();
    }

1つの可変変数を減らすことができるのは常に良いことです。

状態を逆転させる

多くの場合、条件式を逆にして、ネストされた条件式をガードに置き換えることができます。

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital > 0) {
    if (anInstrument.interestRate > 0 && anInstrument.duration > 0) {
      result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
    }
  }
  return result;
}

1つずつ交換してください。しかし、今回はガードステートメントを挿入するときに、対応する条件を逆にする必要があります。

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital <= 0) {
    return result;
  }
  if (anInstrument.interestRate > 0 && anInstrument.duration > 0) {
    result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
  }
  return result;
}

次の条件はもう少し複雑なので、2つのステップで反転を行います。最初に論理NOT演算を追加します。

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital <= 0) {
    return result;
  }
  if (!(anInstrument.interestRate > 0 && anInstrument.duration > 0)) {
    return result;
  }
  result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
  return result;
}

しかし、このような条件式に論理否定を残すと頭がおかしくなるので、次のように簡略化しました。

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital <= 0) {
    return result;
  }
  if (anInstrument.interestRate <= 0 || anInstrument.duration <= 0) {
    return result;
  }
  result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
  return result;
}

これらの2行のロジックは同じ結果を生成するため、[条件式のマージ]と組み合わせることができます。

public int adjustedCapital(Instrument anInstrument) {
  int result = 0;
  if (anInstrument.capital <= 0 || anInstrument.interestRate <= 0 || anInstrument.duration <= 0) {
    return result;
  }
  result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
  return result;
}

この時点で、結果変数は2つのことを行います。最初は0に設定します。これは、ガードステートメントがトリガーされたときの戻り値を表します。次に、最終的な計算の結果を割り当てます。この変数を完全に削除し、1つの変数との二重の責任を回避し、別の変数変数を減らすことができます。

public int adjustedCapital(Instrument anInstrument) {
  if (anInstrument.capital <= 0 || anInstrument.interestRate <= 0 || anInstrument.duration <= 0) {
    return 0;
  }
  return (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
}

参照する

  • 「復興」
  • 「クリーンアーキテクチャ」

 
初めてHUAWEICLOUDの新技術について学ぶには、[フォロー]をクリックしてください〜

おすすめ

転載: blog.csdn.net/devcloud/article/details/124042780