めんどくさがりダイアリー

へっぽこプログラマの備忘録

テーブル処理ってどうなんだろう

仕事でコードを書いていると以下のようなコードを見かける

bool initalize(){
    bool success;

    success = initalizeAAA();
    if(!success){
        return false;
    }

    success = initalizeBBB();
    if(!success){
        return false;
    }

    success = initalizeCCC();
    if(!success){
        return false;
    }

    //...モジュールの初期化関数の呼び出しが続く

    return true;
}

上記のような各モジュールの初期化関数をひとまとめにした関数は
新規にモジュールが増えるたびに関数呼び出しが追加され、
戻り値の判定が増えていくため、サイクロマチック複雑度が
増大して静的解析で警告が出ることがある。

このコードを先輩がリファクタしていたのだが
その結果、以下のようなコードになった。

typedef bool (initFunc)(void);

bool initalize(){
    initFunc funcTable[] = {initalizeAAA,
                            initalizeBBB,
                            initalizeCCC ...};
    int funcTableSize = sizeof(funcTable) / sizeof(funcTable[0]);

    // 初期化関数をループで呼び出す
    for(i = 0; i < funcTableSize; i++){
        if( funcTable[i]() == false ){
            return false;
        }
    }

    return true;
}

上記のようなコードはテーブル処理(テーブルジャンプ?)というらしく
case分が大量にあるルーチンなどを簡略化する際に割と使われる方法らしい。

コードの可読性が下がっているような気がするので
個人的にはあまり好きになれないが
コード量の削減モジュールの拡張性向上にはかなり有用らしい。

参考URL
テーブル処理の鬼と化せ!
[C/C++]テーブルジャンプ