深いネストはバグの温床

深すぎるネストはバグの温床にしかなりません。
できるだけ浅くする努力をしましょう。

例えば、以下のような書き方に慣れてしまっている方が多いように思われます。
この書き方は一見綺麗に見えるのですが、実は意外と読みにくく、修正もしにくいです。

if (!errorFlag) {
    for (int i = 0; i < 100; i++) {
        if (valueList[i] != null) {
            if (hogehoge) {
                (略1)
            } else {
                (略2)
            }
        }
    }
}

 

これだけネストが深いと、デバッグの際に
「一個目のif文の条件はhogeで、ループに入って、二個目のif文はhogeで・・・」
などと覚えながら読む必要があるので大きなタイムロスになってしまいます。

また、仕様変更でif文を追加する場合など、外側のif文の条件が邪魔で無駄に分岐を増やさざるを得なくなったり、条件がバッティングして思わぬ挙動をしたりします。
可読性・保守性の低下を招きますので、減らせるネストは減らしていきましょう。

 

まず、最初にエラーだった時点でreturnしてしまいます。
たったこれだけで、一階層減ります。

if (errorFlag) {
    return;
}
for (int i = 0; i < 100; i++) {
    if (valueList[i] != null) {
        if (hogehoge) {
            (略1)
        } else {
            (略2)
        }
    }
}

 

戻り値を返すのは一番最後?』でも紹介していますが、このreturnの使い方はここでも有効です。

次に、ループの中で何もしなくていい場合はcontinueします。
これで、いとも簡単にもう一階層減ります。

if (errorFlag) {
    return;
}
for (int i = 0; i < 100; i++) {
    if (valueList[i] == null) {
        continue;
    }
    if (hogehoge) {
        (略1)
    } else {
        (略2)
    }
}

 

いかがでしょう、随分読みやすくなったのではないでしょうか?
メソッドの可読性を上げる小技がreturnなら、ループの可読性を上げる小技はcontinueといった感じです。

continueを使いこなせていない方が結構多いように思われますが、この使い方は覚えておいて損はないと思います。

 

最後に、余分なelse文を取ればこのメソッドは完成です。

if (errorFlag) {
    return;
}
for (int i = 0; i < 100; i++) {
    if (valueList[i] == null) {
        continue;
    }
    if (hogehoge) {
        (略1)
        continue;
    }
    (略2)
}

 

一番最初のサンプルのような書き方に慣れてしまっている人は初めは抵抗があるかもしれませんが、慣れると間違いなくこちらの方が読みやすいし修正もしやすいです。

無理して減らすと逆に読みにくくなるケースもあるので一概には言えませんが、ネストは大体三階層ぐらいが限度だと思います。
どうしても四階層や五階層になる場合は、その部分を別メソッドに切り分ければ階層も1メソッドの行数も減るので、可読性が大幅アップすると思います。




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です