こういう人におすすめ

  • プログラミングを始めたばかりの人
  • ネストについてよく分かっていない人

目次

  1. はじめに
  2. ネストとは?
  3. ネストが深くなることにより引き起こされる問題点
  4. ネストを浅くする方法
  5. まとめ

1.はじめに

開発をしていると、どんな言語を使う時でも、条件分岐や繰り返しをよく使いますよね。
そんなときにやりがちなのが「コード内に深いネストを作ってしまう」ということではないでしょうか。
自分で作ってしまうこともあれば、既存のコードに深いネストを見つけて頭を悩ませることもあると思います。

プログラミングを始めたばかりだと、実際にこういった場面に出くわしたときに、

「コードが読みにくくなるから、ネストは浅くしよう!」とよく言うけど、具体的にどうやって浅くすればいいの?

と感じると思います。私もそうでした。

ということで、今回は読みやすいコードに近づけるために「ネストを浅くする方法」についてまとめてみました。

2.ネストとは?

ネストとは、入れ子構造とも呼ばれます。
マトリョーシカのように、あるものの中に同じような構造のものが入っている状態です。
If文、For文、While文などに用いられ、特にFor文、While文では「二重ループ/多重ループ」とも表現します。

使い方によっては処理コストが下がったり、可読性が上がったりとメリットがありますが、基本的には「ネストは深くしてはいけない」「多重ループは避けた方が良い」と言われます。

3.ネストが深くなることにより引き起こされる問題点

・構造が複雑になり、何をしているコードなのか分かりにくくなる
  • どのIF文がどこまで影響を与えているのか
  • 実際にどんな処理をするのか
  • 処理をしたデータはどのような状態のデータなのか

といったことを理解するのに時間がかかってしまいます。
他人が書いたコードはもちろん、書いた本人でさえ「ここって何をやっているコードだったっけ…」となることもあります。

・コードが横に広がり、視覚的に見づらくなる

ネストが深くなると、その分コードが右に広がっていってしまいます。
ディスプレイのサイズによっては、次第に画面に入らなくなり、横スクロールが必要になったりします。

4.ネストを浅くする方法

①ガード節を利用する

ガード節とは、処理の対象外とする条件を、関数やループの先頭でreturn/continue/breakする方法のことです。アーリーリターン/アーリーコンティニューとも呼ばれます。

渡された引数が不正な値でないかチェックしたり、例外的な処理を行うものを先に弾くことで、正常系の処理が分かりやすくなるというメリットがあります。

// before
public function getGender($val, $option) {
    if (isset($option)){
        $result = 3;
    } elseif (isset($val)) {
        if (substr($val, -1) == 0) {
            return 1;
        } else {
            return 2;
        }
    }
    return;
}
// after
public function getGender($val) {
    if (isset($option)) return 3;
    if (isset($val)) return;
    
    if (substr($val, -1) == 0) {
        return 1;
    } else {
        return 2;
    }
}
boolean値を利用する

IF文の中身は必ず boolean 値になるので、true/false で返したいときにはそのまま返り値として使うことができます。

// before
public function IsEvenNumber($number) {
    $result = null;
    if ($number % 2 == 0) {
        $result = true;
    }
    $result = false;
    return $result;
}
// after
public function IsEvenNumber($number) {
    return $number % 2 == 0;
}
③三項演算子を利用する

三項演算子を使うことも選択肢の1つです。しかし、「三項演算子は分かりにくい」と考える人も多いため、使う場合には複雑な処理を入れ込まないようにした方が良いでしょう。

// before
public function getGender($val, $option) {
    if (isset($option)){
        $result = 3;
    } elseif (isset($val)) {
        if (substr($val, -1) == 0) {
            return 1;
        } else {
            return 2;
        }
    }
    return;
}
// after
public function getGender($val) {
    if (isset($option)) return 3;
    if (isset($val)) return;
    
    return substr($val, -1) == 0 ? 1 : 2;
}
④メソッドをモジュール化する

ネストを少なくする根本的解決法ではありませんが、可読性を上げる方法の1つとして「メソッドのモジュール化を検討する」ことが挙げられます。

// before
if ($option) {
    if (...) {
        foreach (...) {
            // 処理
        }
    } 
} else {
    foreach ($array as $item) {
        if (...) {
            if (...) {
                // 処理
            }
        }
    }
}
// after
if ($condition) {
    $this->hoge();
} else {
    $this->fuga($array);
}

5.まとめ

既存のコードをリファクタリングするのは、様々な事情で難しいことも多いです。
「後から直せばいいか…」とはいかない場合の方が多いので、コードを書くときには「別の人が後で読んでも分かりやすいか?」ということを念頭に置いて書くことが重要ですね。