はじめに
ソースコードの可読性と保守性を向上させるための、if文のネストを減らす方法について簡単にまとめてみました。初学者の方にとって参考になるかもしれません。
サンプルプログラムはPythonで記述していますが、汎用的なものなので、他の言語でも適用できる場合がほとんどです。
※全てのケースにおいて適用できるわけではありません。また、完全にelif(else if)やelseを使わないという制約は、コードの論理的な構造を表現するための有用なツールを制限してしまう可能性がありますので、適切なバランスを見つけることも重要かと思います。
サンプルプログラム
内容
- 年齢(age)をもとに飲酒できるかどうかを判定する
- 年齢が0未満の場合は「You are not born yet.」と出力
- 年齢が0以上20未満の場合は「You cannot drink.」と出力
- 年齢が20以上の場合は「You can drink.」と出力
- 年齢が数字以外の場合は「Invalid age.」と出力
実際どう実装すれば良いのでしょうか。まず悪い例
を見てみましょう。
age = 20
if isinstance(age, int):
if age < 0:
print("You are not born yet.")
elif age >= 0 and age < 20:
print("You cannot drink.")
else:
print("You can drink.")
else:
print("Invalid age.")
一見問題なさそうなプログラム(実際問題なく動く)ですが、いくつかの問題点があります。
問題点&改善点
条件のネストをなるべく避ける
上記の例では、ネストしたif文が使われていて、条件が入れ子構造
になっています。
if isinstance(age, int):
if age < 0:
pass
二重入れ子構造になっているので、まだそこまでわかりにくいわけではないかもしれませんが、条件が多くなり、ネストが深くなる
と、プログラムの可読性と保守性が低くなってしまいます
。
関数として切り出す
上述のように、if文やelse文のネストが複雑になりがちです。この場合、判定処理を関数として切り出すと良いでしょう。
def can_drink(age):
pass
age = 20
result = can_drink(age)
print(result)
関数として切り出したら、次に判定条件を修正する必要があります。
一致する条件から結果をreturnする
サンプルプログラムでは、まず年齢(age)が数字かどうかを判定し、数字の場合は次の条件の判定に入っているので、入れ子構造になっています。条件のネストを避けるために、判定条件を変更し、先に一致する条件から結果をreturnしていくと良いでしょう。
def can_drink(age):
if not isinstance(age, int):
return "Invalid age."
isinstance(age, int)
がTrue
の場合に次の判定に入るのではなく、isinstance(age, int)
がFalse
の場合に「Invalid age.」を返せば、年齢(age)が数字でない時点で処理が終了します。
※戻り値がない場合はreturnのみを記述します。
同じように他の条件の記述方法も修正すれば、else
やelif
の使用を避けることができます。
def can_drink(age):
if not isinstance(age, int):
return "Invalid age."
if age < 0:
return "You are not born yet."
if age < 20:
return "You cannot drink."
return "You can drink."
このように判定条件を修正し、いずれも一致しない場合のデフォルトの戻り値を最後に記述します。
リファクタリング
以下、上記の問題点と改善点をもとにリファクタリングを行った後のプログラムの一例です。
def can_drink(age):
if not isinstance(age, int):
return "Invalid age."
if age < 0:
return "You are not born yet."
if age < 20:
return "You cannot drink."
return "You can drink."
age = 20
result = can_drink(age)
print(result)
まとめ
- 条件のネストをなるべく避ける
- 判定処理を関数として切り出す
- 一致する条件から結果をreturnする