ガード節による入れ子条件記述の置き換え

リファクタリング」の「ガード節による条件記述の置き換え」
って項目がまさに、
ifの入れ子になるような処理を、関数の最初で値検査してreturn(あるいは例外をスロー)に置き換えるって話だったと思います。

途中でreturn編 ちょっとりふぁくと - 神様なんて信じない僕らのために


これですね。

double getPayAmount() {
  double result;
  if (_isDead) result = deadAmount();
  else {
       if (_isSeparated) result = separatedAmount();
       else {
           if (_isRetired) result = retiredAmount();
           else result = normalPayAmount();
       }
  }
  return result;
}
double getPayAmount() {
  if (_isDead) return deadAmount();
  if (_isSeparated) return separatedAmount();
  if (_isRetired) return retiredAmount();
  return normalPayAmount();
}

if-then-else構造が使われるときは、if部にもelse部にも同じウエイトが置かれています。これは、プログラムの読み手に対して両方とも等しく起こり得ること、等しく重要であることを伝えます。逆に、ガード節は「めったに起きないが、起きたときには、何もしないで出て行く」ことを伝えます。

リファクタリング―プログラムの体質改善テクニック


Martin Fowlerは、

if (...) {
    // 処理1
} else {
    // 処理2
}
if (...) {
    // 処理1
    return;
}
// 処理2

この2つのコードは、

  • 上のコードでは処理1も処理2も対等
  • 下のコードでは処理1は特殊な場合で、ほとんどの場合は処理2

と、異なるイメージを与えると言っている。


メソッドの途中でreturnする例としては、null安全なメソッドで引数のnullチェックしたあととかはよくある話。
引数にnullを許さないメソッドでも、NullPointerExceptionとかが出るのを待つんじゃなくて、メソッドの先頭でチェックして、IllegalArgumentExceptionとかを投げたほうが分かりやすいのもよくある話。


メソッド途中でのreturnは大好きですよ。
それ以降、その状態のことが無視できるから。