이 예제는 extract till you drop(extract method를 수행할 수 없을 때까지 수행)을 한 후에 남게되는 많은 작은 private method들을 역할에 맞게 다른 클래스로 위치시키는 것을 보여준다.
extract till you drop은 github, youtube에서 자세히 보실 수 있습니다.
package abstract_till_you_drop;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
abstract class SymbolReplacer {
protected String stringToReplace;
protected List alreadyReplaced = new ArrayList();
SymbolReplacer(String s) {
this.stringToReplace = s;
}
String replace() {
Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)");
Matcher symbolMatcher = symbolPattern.matcher(stringToReplace);
while (symbolMatcher.find()) {
String symbolName = symbolMatcher.group(1);
if (getSymbol(symbolName) != null && !alreadyReplaced.contains(symbolName)) {
alreadyReplaced.add(symbolName);
stringToReplace = stringToReplace.replace("$" + symbolName, getSymbol(symbolName));
}
}
return stringToReplace;
}
abstract protected String getSymbol(String symbolName);
}
package abstract_till_you_drop;
public class MyReplacer extends SymbolReplacer {
MyReplacer(String s) {
super(s);
}
@Override
protected String getSymbol(String symbolName) {
return "__";
}
}
package abstract_till_you_drop;
import org.junit.Test;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
public class SymbolReplacerTest {
@Test
public void foo() {
MyReplacer replacer = new MyReplacer("$ss aa $bb dd ff ss");
assertThat(replacer.replace(), is("xx"));
}
}
테스트를 실행시켜서 시스템이 원하는 값을 알아내고 이를 이용하여 테스트를 성공시킨다. <- characterization test
symbolPattern, symbolMatcher를 field로 추출 큰 메소드를 작은 메소드를 extract하기 전의 사전 작업. 이 작업을 수행하면 extract method할 때 parameter로 전달할 필요가 없어진다.
- symbolMatcher, symbolPattern는 nextSymbol에서만 사용됨.
- 다른 속성들보다 보다 응집도가 높거나 밀접하게 관계된 2개 이상의 속성들이 존재하는 경우가 있다.
- 이런 속성들을 별도의 클래스로 추출하면 가독성이 좋아진다.
symbolMatcher, symbolPattern를 SymbolIterator로 이동시키기 위해 static으로 변경. 그래야 intellij에서 move 가능.
가독성을 위해 아래와 같이 extract method를 수행
symbolExpression은 SymbolTranslator와 밀접한 관계를 갖는다. 따라서 SymbolTranslator로 이동시킨다.
replaceSymbol은 symbolTranslator의 2개의 메소드를 호출한다. feature envy다. SymbolTranslator의 translate 메소드로 이동하자.
2개의 메소드 호출을 IDE의 기능으로 이동시킬 수 없다. 먼저 2개의 메소드 호출을 translate 함수로 추출한다.