読者です 読者をやめる 読者になる 読者になる

アラタナエンジニアブログ

aratana Engineer's Blog

世界からelse句が消えたなら 〜オブジェクト指向エクササイズ ルール2〜

この記事はアラタナアドベントカレンダー13日目の記事です。

f:id:kimesawa:20161202085600j:plain

世界から猫が消えたなら、とても困ってしまうのですが、else句が消えるのはとてもいいことですね。

f:id:kimesawa:20161213012401p:plain

以前、オブジェクト指向エクササイズというのを紹介しました。
lab.aratana.jp

そのなかの「ルール2:else 句を使用しないこと」を具体的にどうすればいいのか?というが今回のテーマです。

えっ?て思いましたか?else句の何がよくないのか・・・・・

という話は一旦置いておいて、else句を書かないで済む方法をいくつかご紹介します。

ガード節

Boolean isWeekday(){
  Boolean result;

  if( isSaturday ){
      result = false;
  }else{
      if( isSunday ){
        result = false;
      }
      result = true;
  }
  return result;
}

これを、このようにリファクタリングします。

Boolean isWeekDay(){
  if( isSaturday ) return false;
  if( isSunday ) return false;
    
  return true;
}

ポイントはifの結果でreturnしてしまう「早期リターン」と、特殊なケースや異常ケースは先にチェックして早期リターンしてしまう「ガード節」です。

ここで重要なのは、「メソッドの出口は一つだけというルールに縛られる必要はない」ということです。
ただし、メソッドの出口が複数あっても理解しやすくするために、メソッドの行数を少なくする必要があります。

早期リターンやガード節を駆使してelse句を排除し、メソッドの行数を少なく保ちましょう。

ポリモーフィズム

Date nextRepeatTaskDate(){
  Date nextDate;

  if( isDaily ){
     nextDate = tomorrow();
  }else{
     if( isWeekly ){
        nextDate = nextWeek();
     }else{
        nextDate = nextMonth();
     }
  } 

  return nextDate();
}

これをこうリファクタリングしましょう。

interface RepeatTask{
    Date nextDay();
}

class DailyTask implements RepeatTask{
    Date nextDay(){
       return tomorrow();
    }
}

class WeeklyTask implements RepeatTask{
    Date nextDay(){
       return nextWeek();
    }
}

class MonthlyTask implements RepeatTask{
    Date nextDay(){
       return nextMonth();
    }
}

Date nextRepeatTaskDate(){
    return task.nextMonth();
}

if分そのものがなくなってしまいましたね。

場合ごとに型を作成することで、ifでの判定自体をなくしてしまう方法です。

このように、同名のメソッドや型などをオブジェクトの種類に応じて使い分けることができる、オブジェクト指向言語の持つ特徴を「ポリモーフィズム」とか「多態性」といいます。

ポリモーフィズムを使うと、ifどころか、switch文も不要です。

ちなみに、クラス図で書くと以下のような感じです。

f:id:kimesawa:20161214003412p:plain

さて、ここまで、else句をなくすいくつかの方法をお伝えしてきましたが、ここで冒頭のelse句の何がよくないのか?について。

if( isXXX ){
 ②
}else{
 ③
}
④

上記のelse句を使ったソースは、
①→②→④
または、
①→③→④
と2通りの流れがあるだけでなく、どちらの流れも通らない道があり、ソースを読むときにはそこを飛ばして理解する必要があります。

これを読むのはソースが長くなるほどしんどくなるはずです。

対して、else句をなくした「早期リターン」や「ガード節」・「ポリモーフィズム」を使ったソースは、こういった読みにくさが解消されています。

ぜひ、これらのテクニックを活用してみてください。

また、他にも条件分岐についてのテクニックがあります。ぜひ、この本の「第9章 条件分岐の単純化」
を読んでみてください。

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

さて、次回のアドベントカレンダーも僕です。題して、「YO YO YO ♫このラップじゃないラップについて 〜オブジェクト指向エクササイズ ルール3及び8〜」です。

f:id:kimesawa:20161202085600j:plain