Menu

FrontPage

Eclipseプラグイン
Eclipse小技集
リファクタリング講座
テスティングフレームワーク JUnit
MSDEについて



The 20 newest affair
2010-09-092010-09-082010-09-072010-09-062010-09-012010-08-312010-08-272010-08-242010-08-232010-08-172010-08-162010-07-302010-07-212010-07-132010-06-272010-06-182010-06-172010-06-16

はじめに


   メソッドの抽出をすると、リファクタリングしやすくなることがあります。
   ここでは、簡単に実践可能なリファクタリングを紹介します。
   適用前と適用後の違いを見比べてみてください。



名前の変更

 目的を正しく表すように、変数やメソッドの名前を変更する

適用前
  boolean osFlag = platform.toUpperCase().indexOf(“WINDOWS”) > -1;
  boolean ieFlag = browser.toUpperCase().indexOf(“IE”) > -1;

  if (osFlag && ieFlag) {
    // 省略
  }

適用後
  boolean isWindows = platform.toUpperCase().indexOf(“WINDOWS”) > -1;
  boolean isIEBrowser = browser.toUpperCase().indexOf(“IE”) > -1;

  if (isWindows && isIEBrowser) {
    // 省略
  }


メソッドの抽出

 長すぎるメソッドや、コメントが無ければ理解できないメソッドに対して、その断片をメソッド化し、目的をあらわすような名前をつける

適用前
  if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
    // 省略
  }

適用後
  if (isLeapYear(year)) {
    // 省略
  }

-----------------------------------------------------------------------

private boolean isLeapYear(int year) {
  return
year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}



説明用変数の導入

 式の結果、または部分的な結果をその目的を説明する名前をつけた一時変数に代入する

適用前
  if ((platform.toUpperCase().indexOf(“WINDOWS”) > -1) && (browser.toUpperCase().indexOf(“IE”) > -1)) {
    // 省略
  }
適用後
  final boolean isWindows = platform.toUpperCase().indexOf(“WINDOWS”) > -1;
  final boolean isIEBrowser = browser.toUpperCase().indexOf(“IE”) > -1;

  if (isWindows && isIEBrowser) {
    // 省略
  }


制御フラグの削除

 メソッドの出口を複数にし、制御フラグを削除する

適用前

  // 省略

  String[] languages = {“C”, “C++”, “Java”, “Perl”};

  // 省略

  boolean found = false;

  for (int i = 0; i < languages.length; i++) {
    if (languages[i].indexOf(“Java”) > -1) {
      found = true;
      break;
    }
    if (languages[i].indexOf(“C++”) > -1) {
      found = true;
      break;
    }
  }


  if (found) System.out.println(“OOP language Found ...”);

  // 省略


「メソッドの抽出」適用後

  // 省略

  String[] languages = {“C”, “C++”, “Java”, “Perl”};

  // 省略

  if (isOOPLanguage(languages)) System.out.println(“OOP language Found ...”);

  // 省略

------------------------------------------------------------------------------

private boolean isOOPLanguage(String[] languages) {

  boolean found = false;

  for (int i = 0; i < languages.length; i++) {
    if (languages[i].indexOf(“Java”) > -1) {
      found = true;
      break;

    }
    if (languages[i].indexOf(“C++”) > -1) {
      found = true;
      break;

    }
  }
  return found;
}

「制御フラグの削除」適用後

  // 省略

  String[] languages = {“C”, “C++”, “Java”, “Perl”};

  // 省略

  if (isOOPLanguage(languages)) System.out.println(“OOP language Found ...”);

  // 省略

------------------------------------------------------------------------------
private boolean isOOPLanguage(String[] languages) {

  for (int i = 0; i < languages.length; i++) {
    if (languages[i].indexOf(“Java”) > -1) return true;
    if (languages[i].indexOf(“C++”) > -1) return true;
  }

  return false;
}



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

 ルートが不明確な条件付振る舞いを整理し、ルートを明確にする

適用前

  String number = “12345”;

  // 省略

  boolean isAnswerNumber = false;
  if (number == null) {
    isAnswerNumber = false;
  } else {
    if (number.length() == 4) {
      if (number.getBytes().length == 4) {
        isAnswerNumber = true;
      } else {
        isAnswerNumber = false;
      }
    } else {
      isAnswerNumber = false;
    }
  }


  if (!isAnswerNumber) System.out.println(“Answer is incorrect ...”);

  // 省略


「メソッドの抽出」適用後

  String answerNumber = “12345”;

  // 省略

  if (!isAnswerNumber(answerNumber)) System.out.println(“Answer is incorrect ...”);

  // 省略

-----------------------------------------------------------------------
private boolean isAnswerNumber(String number) {

  boolean isAnswerNumber = false;
  if (number == null) {
    isAnswerNumber = false;
  } else {
    if (number.length() == 4) {
      if (number.getBytes().length == 4) {
        isAnswerNumber = true;
      } else {
        isAnswerNumber = false;
      }
    } else {
      isAnswerNumber = false;
    }
  }
  return isAnswerNumber;
}


「制御フラグの削除」適用後

  String answerNumber = “12345”;

  // 省略

  if (!isAnswerNumber(answerNumber)) System.out.println(“Answer is incorrect ...”);

  // 省略

-----------------------------------------------------------------------
private boolean isAnswerNumber(String number) {

  if (number == null) {
    return false;
  } else {
    if (number.length() == 4) {
      if (number.getBytes().length == 4) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
}


「入れ子条件記述の置き換え」適用 その1

  String answerNumber = “12345”;

  // 省略

  if (!isAnswerNumber(answerNumber)) System.out.println(“Answer is incorrect ...”);

  // 省略

-----------------------------------------------------------------------
private boolean isAnswerNumber(String number) {

  if (number == null) return false;
  if (number.length() == 4) {
    if (number.getBytes().length == 4) {
      return true;
    } else {
      return false;
    }
  } else {
    return false;
  }

}


「入れ子条件記述の置き換え」適用 その2

  String answerNumber = “12345”;

  // 省略

  if (!isAnswerNumber(answerNumber)) System.out.println(“Answer is incorrect ...”);

  // 省略

-----------------------------------------------------------------------
private boolean isAnswerNumber(String number) {

  if (number == null) return false;
  if (number.length() != 4) return false;
  if (number.getBytes().length == 4) {
    return true;
  } else {
    return false;
  }
}


「入れ子条件記述の置き換え」 適用後

  String answerNumber = “12345”;

  // 省略

  if (!isAnswerNumber(answerNumber)) System.out.println(“Answer is incorrect ...”);

  // 省略

-----------------------------------------------------------------------
private boolean isAnswerNumber(String number) {

  if (number == null) return false;
  if (number.length() != 4) return false;
  if (number.getBytes().length != 4) return false;

  return true;
}



Attached File: [Attached File All List]

Lastmodified: 2007-03-25 (日) 13:34:02 (1263d)