ガード節による入れ子条件記述の置き換え
「リファクタリング」の「ガード節による条件記述の置き換え」
途中でreturn編 ちょっとりふぁくと - 神様なんて信じない僕らのために
って項目がまさに、
ifの入れ子になるような処理を、関数の最初で値検査して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は大好きですよ。
それ以降、その状態のことが無視できるから。