7

次の C++ コードをリファクタリングするにはどうすればよいですか? プログラムで C++11 を使用しています

void f(int a, int b, int c, int d, int e, int f) {

  // MAX1..MAX6 are constants, N1..N6 are constants
    if( a > MAX1) {
        .. code block 1..
    }
    else if(b > MAX2) {
        .. code block 2..
    }
    else if(c > MAX3) {
        .. code block ..
    }
    else if(d > MAX4) {
        .. code block 3 ..
    }
    else if(e > MAX5) {
        .. code block 4 ..
    }
    else if(f > MAX6) {
        .. code block5 ..
    }
    else if(( a > N1) && ( b > N2)) {
            .. code block 6 ..
    }
    else if(( c > N3) && ( d > N4)) {
            .. code block 7 ..
    }
    else if (( e > N5) && ( f > N6)) {
            .. code block 8 ..
    }
    else if (( a > N1) && ( b > N2) && (d > N4)) {
            .. code block 9 ..
    }
    else if (..some combination of (a > N1) to (f > N6)...) {
            // there are more than 30 such combinations in my code
            .. code block XX ..
    }
    else {
            .... code block ....
    }
4

6 に答える 6

0

あなたが持っているものは不合理ではないようですが、本当にリファクタリングしたい場合は、列挙型を作成できます

enum class CaseSelect {CASE0, CASE1, CASE2};

次に、現在のifツリーに非常によく似た関数を作成し、各コードブロックが適切な列挙型を返します。

次に、列挙型を使用して case ステートメントを作成し、それぞれに適切なロジックを含めます。

あまりメリットはありませんが、状態を選択するロジックを操作ロジックから分離します。これは、複数行のステートメントの場合に明確にするのに役立つ場合があります

于 2013-09-18T16:53:58.143 に答える
0

したがって、相互に排他的な整数範囲 (xi から yi) の離散数 N があり、与えられた入力 z がどの範囲であるかに応じてコードのブロックを呼び出したいとします。

  • 二分木を使用してstd::map、各範囲の開始点と対応するラムダを格納します。
  • std::lower_boundon z を呼び出して候補範囲を見つけます
  • 次に、その範囲の上限を z に対してチェックします。
  • 内部にある場合は、ラムダを呼び出します

これにより、大きな if-else チェーンの O(n) と比較して O(log(N)) の時間が得られます。

于 2013-09-18T17:20:15.893 に答える
-1

多くのルールがある場合、関数オブジェクト (例: ラムダ) がレスキューのために存在する可能性があります。

デモンストレーションのために少し単純化しましたが、引数は3つだけです...

そして、この場合、非チェックには安全な値があると思います0(それがなくても生きていけるかもしれませんが、そうすると見苦しくなります)。

#include <iostream>
#include <functional>

struct Rule {
    int a;
    int b;
    int c;
    std::function<int()> fun;
};

Rule rules[]{
    { 10, 0, 0, []() { std::cout << "First!"; return 0;} },
    { 0, 20, 0, []() { std::cout << "Second!"; return 1;} }
};

int f(int a, int b, int c) {
    for (Rule rule : rules) {
        if ((rule.a == 0 || a > rule.a)
         && (rule.b == 0 || b > rule.b)
         && (rule.c == 0 || c > rule.c))
            return rule.fun();
    }
    std::cout << "Not match!";
    return 2;
}

int main() {
    f(5, 23, 3);
};
于 2013-09-18T16:56:43.497 に答える