初めて「リーダブルコード」を読んで、個人的に気になったネストの入れ子問題について追加で調べてみました。
すると、ネストを浅くする際に用いる早期リターンについて様々な意見がありました。
調べたことを踏まえて、まとめてみました。
ネストの深いコードは理解しにくい
ネストが深いプログラムを見ると括弧が多くて混乱します。
また「条件1がtrueで条件2がfalseで…」のように辿った条件を覚えておかないといけません。
function judge() {
if (条件1) {
// 処理A
if (条件2) {
// 処理B
} else {
if (条件3) {
// 処理C
if (条件4) {
// 処理D
if (条件5) {
// 処理E
}
}
}
}
}
}
早期リターンでネストを浅くする
上記のコードでなるべくネストを浅くしてみます。
function judge() {
if (! 条件1) return;
// 処理A
if (条件2) {
// 処理B
return;
}
if (! 条件3) return;
// 処理C
if (! 条件4) return;
// 処理D
if (! 条件5) return;
// 処理E
}
しかし、これは本当にプログラムとして改善されたのでしょうか?
結局どうなの?
ネストを浅くしたことによる影響を考えてみます。
コードが見やすくなった?
括弧の数が減り、横に広がることもなくなりました。
すっきりして見やすくなったと思います。
覚えておかないといけない条件は減らせた?
また「条件1がtrueで条件2がfalseで…」のように辿った条件を覚えておかないといけません。
冒頭で述べた上記の部分についてです。
ガード節を用いることで「条件1がfalse」の場合を以降で考えなくても良くなります。
ただ結局は「条件1がtrueで…」と考えているのと同義ですので、ネストを浅くしても条件は減っていません。
コードが理解しやすくなった?
コードは理解しやすくなければならない
「リーダブルコード」のはじめに述べられている内容です。
これが達成できていないのであれば、ネストを浅くしても意味がありません。
改めて今回の例に挙げたコードを見てみます。
else文を使用していた部分が直感的に把握しづらくなっています。
そこで以下のように書き直してみました。
function judge() {
if (! 条件1) return;
// 処理A
if (条件2) {
// 処理B
return;
} elseif (条件3) {
// 処理C
if (! 条件4) return;
// 処理D
if (! 条件5) return;
// 処理E
}
}
当初よりネストが浅くなり、分岐も直感的に把握できる状態になりました。
(別メソッドに分ければもっと見やすくなりますが、今回はここまで)
まとめ
ネストの入れ子問題、およびその解決で用いられる早期リターンについてまとめてみました。
様々な意見が交わされているということはそれだけ難しい問題ということだと思います。
経験を積みながら、その場に応じた書き方ができるようになりたいです。
参考文献/サイト
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック