第 6 章 支援環境の適用実験 29
6.1.3 ツールによる BadSmell の発見
Long Methodの基準値は15行以上とする。
1. Long Method(26)に対してメソッドの抽出を行う 2. Feature Envyに対してメソッドの移動を行う 3. Long Method(15)に対してメソッドの抽出を行う 4. Feature Envyに対してメソッドの移動を行う
初期状態
図6.1のProblem Viewから、Customerクラスのstatementメソッドが26行であるゆ
えにLong Methodであることが確認でき、このソースコードに対してリファクタリング
が必要であるとわかる。
又、図6.2のエディタのマーカから、Long Methodである箇所のを位置を視覚的に確認 することができる。
Long Methodを解決するためのリファクタリング操作を確認したところ、図6.3の結
果となり、メソッドの抽出(Extract Method)と一時変数の置き換え(Replace Temp With
Query)で解決できる事がわかる。
図 6.1: Problem View
図 6.2: エディタによるLong Methodの箇所の表現
図 6.3: Long Methodを解決するリファクタリング操作
Long Methodに対してメソッドの抽出を行う
Long Methodを解決するため、6.4のとおりメソッドの抽出を行い、statementメソッ ドの一部をamountForメソッドとして抽出した。
その結果、図6.5のProblem Viewからstatementメソッドは15行まで行数が少なく
更に、抽出したメソッドであるamountForがFeature Envyであることが確認でき、先 ほどのメソッドの抽出によりstatementメソッドに潜んでいたBadSmellを発見すること ができた。
新たに発見したFeature Envyを解決するためのリファクタリングを確認したところ、
図6.3の結果となり、メソッドの移動(Move Method)で解決できることがわかる。
public String statement(){ public String statement(){
... ...
while (rentals.hasMoreElements()){ while (rentals.hasMoreElements()){
double thisAmount = 0; Rental each = (Rental) rens ...
Rental each = (Rental)ren ...; double thisAmount = amountFor(each);
switch (each.getMovie() ...){ ...
case Movie.REGULAR: }
... ...
} }
... → public double amountFor(Rental each) {
} double thisAmount = 0;
... switch (each.getMovie() ...)){
} case Movie.REGULAR:
...
}
return thisAmount;
}
図 6.4: amountForメソッドを抽出
図 6.5: Problem View
図 6.6: Feature Envyを解決するリファクタリング操作
Feature Envyに対してメソッドの移動を行う
Feature Envyを解決するため、6.7のとおりメソッドのを移動を行い、amountForメ ソッドをCostomerクラスからRentalクラスへと移動した
その結果、図6.8のProblem ViewからFeature Envyが消えたことが確認でき、リファ クタリング操作によりBadSmellが消滅したことがわかる。
しかし、未だLong Methodの方は消滅していないため、引き続きリファクタリングを 行う必要がある。
public class Customer{ public class Customer{
... ...
public String statement(){ public String statement(){
... ...
while (rentals.hasMore ...){ while (rentals.hasMore ...){
Rental each = (Rental) ... Rental each = (Rental) ...
... = amountFor(each); ... = each.amountFor();
... ...
} }
... ...
} }
public double amountFor(Rental each) { ...
double thisAmount = 0; → }
switch (each.getMovie() ...)){ public class Rental{
case Movie.REGULAR: ...
... public double amountFor(){
} double thisAmount = 0;
return thisAmount; switch (getMovie() ...)){
} case Movie.REGULAR:
... ...
} }
return thisAmount;
} ...
}
図 6.7: amountForメソッドの移動
図 6.8: Problem View
Long Methodに対してメソッドの抽出を行う
Long Methodを解決するため、6.9のとおりメソッドの抽出を行い、statementメソッ ドの一部をgetFrequentRenterPointsメソッドとして抽出した。
その結果、図6.10のProblem ViewからLong Methodが消えたことが確認でき、リファ クタリング操作によりBadSmellが消滅したことがわかる。
しかしながら、抽出したメソッドgetFrequentRenterPointsがFeature Envyであるた め、これを解消するためリファクタリングを続けなければならない。
public class Customer{ public class Customer{
... ...
public String statement(){ public String statement(){
... ...
while (rentals.hasMore ...){ while (rentals.hasMore ...){
... ...
if((each.getMovie() ... frequentRenterPoints =
getFrequentRenterPoints(...
frequentRenterPoints = ... ...
else }
frequentRenterPoints++ ...
... → }
} ...
... public int getFrequentRenterPoints(...{
} if((each.getMovie() ...
... frequentRenterPoints = ...
} else
frequentRenterPoints++
return frequentRenterPoints;
} ...
}
図 6.9: amountForメソッドの移動
図 6.10: Problem View
Feature Envyに対してメソッドの移動を行う
Feature Envyを解決するため、6.11 のとおりメソッドのを移動を行い、getFrequen-tRenterPointsメソッドをCostomerクラスからRentalクラスへと移動した
その結果、図6.12のProblem ViewからFeature Envyが消えたことが確認でき、リファ クタリング操作によりBadSmellが消滅したことがわかる。
又、これ以上BadSmellが見つからないことから、リファクタリングを終了する。
public class Customer{ public class Customer{
... ...
public String statement(){ public String statement(){
... ...
while (rentals.hasMore ...){ while (rentals.hasMore ...){
... ...
frequentRenterPoints = frequentRenterPoints =
getFrequentRenterPoints ... each.getFrequentRenter ...
... ...
} }
... ...
} → }
... ...
public int getFrequentRenter ... }
if((each.getMovie() ... public class Rental{
frequentRenterPoints = ... ...
else public int getFrequentRenter...{
frequentRenterPoints++ if((getMovie() ...
return frequentRenterPoints; frequentRenterPoints = ...
} else
... frequentRenterPoints++
} return frequentRenterPoints;
} ...
}
図 6.11: amountForメソッドの移動
図 6.12: Problem View