• 検索結果がありません。

ツールによる BadSmell の発見

ドキュメント内 リファクタリング支援の自動化の研究 (ページ 42-50)

第 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

ドキュメント内 リファクタリング支援の自動化の研究 (ページ 42-50)

関連したドキュメント