1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「早期リターン」でコードをもっとシンプルに!

Last updated at Posted at 2024-12-18

image.png

理屈じゃないんだ、直感だ。人間だもの。

プログラミングを学び始めたばかりの人が早い段階で経験するのが、条件分岐を使ったロジックの記述に関するモヤモヤです。たとえば、以下のようなコードを書いたことはありませんか?

function judgeSchoolLevel($age) {
    if ($age >= 6 && $age <= 11) {
        return "小学生";
    } elseif ($age >= 12 && $age <= 14) {
        return "中学生";
    } elseif ($age >= 15 && $age <= 17) {
        return "高校生";
    } else {
        return "対象外";
    }
}

このコードは一見問題なさそうだし、これくらいでモヤモヤを感じる人も少なそうですが(感じる人は素質あるよ!)、理屈っぽくないですか? 小学生でも中学生でも高校生でもなければって? もっと読みやすく書ける方法があります。それが 早期リターン です。

早期リターンを使った改善例

早期リターンを使えば、条件を満たした時点で結果を返すことができます。上記のコードを早期リターンで書き直すと、以下のようにシンプルになります!

function judgeSchoolLevel($age) {
    if ($age >= 6 && $age <= 11) {
        return "小学生";
    }
    if ($age >= 12 && $age <= 14) {
        return "中学生";
    }
    if ($age >= 15 && $age <= 17) {
        return "高校生";
    }
    return "対象外";
}

このように書くことで、

  • 条件ごとに独立して記述できる
  • 余分な変数 ($result) を使わなくて済む
  • 読みやすくなる

といったメリットがあります。elseifが出てこないのが特徴的ですね!

いや、分かりにくい?

もっと複雑なケースでは?

前述の例ではそもそも簡単すぎて早期リターンのメリットが分かりづらいかもしれません。より複雑な例を見てみましょう。

悪例:早期リターンを使わないコード

次は、ユーザーの認証状態や権限を確認して処理を実行するコードです。

function processUserAction($user) {
    $result = '';

    if ($user) {
        if ($user->isLoggedIn()) {
            if ($user->hasPermission('edit')) {
                if ($user->isActive()) {
                    if ($user->isVerified()) {
                        $result = '編集処理を実行しました';
                    } else {
                        $result = 'アクティブですが、認証されていません';
                    }
                } else {
                    if ($user->hasPermission('view')) {
                        if ($user->isVerified()) {
                            $result = 'アカウントは非アクティブですが、閲覧権限があり、認証されています';
                        } else {
                            $result = 'アカウントは非アクティブで、認証されていません';
                        }
                    } else {
                        $result = 'アカウントが非アクティブで、権限がありません';
                    }
                }
            } else {
                if ($user->isActive()) {
                    $result = 'アクティブですが、編集権限がありません';
                } else {
                    $result = '非アクティブで、編集権限がありません';
                }
            }
        } else {
            $result = 'ログインしていません';
        }
    } else {
        $result = 'ユーザー情報がありません';
    }

    return $result;
}

なんだかよく分かりませんね!
ネスト構造が美しいと思う人もいるんですけど、美しいと思っていても理解してなかったりしませんか?それじゃダメなんです!

というか、ネスト構造としては、これは美しいほうです。現場のコードはこんなもんではないですね?

問題点:

  • ネストが深く、何をしているのか分かりづらい。
  • 条件の優先順位や意図が見えにくい。
  • 修正や追加が困難。

良例:早期リターンを使ったコード

以下は、早期リターンを用いて書き直したコードです。

function processUserAction($user) {
    if (!$user) {
        return 'ユーザー情報がありません';
    }

    if (!$user->isLoggedIn()) {
        return 'ログインしていません';
    }

    if (!$user->hasPermission('edit')) {
        return !$user->isActive()
            ? '非アクティブで、編集権限がありません'
            : 'アクティブですが、編集権限がありません';
    }

    if (!$user->isActive()) {
        return $user->hasPermission('view') && $user->isVerified()
            ? 'アカウントは非アクティブですが、閲覧権限があり、認証されています'
            : 'アカウントは非アクティブで、認証されていません';
    }

    if (!$user->isVerified()) {
        return 'アクティブですが、認証されていません';
    }

    return '編集処理を実行しました';
}

どうでしょう、とても分かりやすくなったと思いませんか?
三項演算子をバランスよく使っているのも重要ポイントです!

改善点:

  • ネストがなくなり、条件が独立して記述されている。
  • 各条件の意図が明確。
  • 修正や追加が簡単。

早期リターンの利点

早期リターンを使うことで、以下のような利点があります:

  1. 読みやすさ

    • 条件ごとに直線的に記述できるため、コードの流れが分かりやすくなります。
  2. 保守性の向上

    • 条件を追加したり修正したりする際の影響範囲を抑え、ミスを減らせます。
  3. バグの防止

    • 不要な変数の生成を避け、ロジックの意図がより明確になります。

結論

早期リターンは、コードを簡潔かつ明確に保つための有効な手法です。特に複雑なロジックを扱う場合、その効果は絶大です。ぜひあなたのプロジェクトのコードにも取り入れてみてください!こういうのが嫌いなPMさんもいるので叱られない程度にね笑

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?