목차
JUnit에서 가져온 실제 코드를 살펴보자.
ComparisonCompactor 모듈
→ 문자열 비교 오류를 파악할 때 유용한 코드로 두 문자열을 받아 차이를 반환.
ex) ABCDE와 ABXDE를 받아서 <...B[X]D...>반환
테스트코드
→ 위 테스트 케이스로 ComparisonCompactor 모듈에 대한 코드 커버리지를 분석해보면 100%가 나오므로 테스트 케이스가 모든 행, 모든 if문, 모든 for 문을 실행한다는 것을 의미.
원래의 ComparisonCompactor 모듈
→ 코드가 잘 분리되어 있고 표현력이 적절하며 코드가 단순.
→ 긴 표현식 몇 개와 이상한 +1 등이 눈에 띄지만 디팩터링 한 결과인 [15-3]과 비교했을 때 전반적으로 휼륭
⇒ 원래의 모듈은 훌륭하지만 보이스카웃 규칙에 따라 [15-2]를 개선한다.
인코딩을 피하라[N6]
→ 멤버 변수 앞에 붙인 중복되는 정보인 접두어 f 제거 ( ∵ 오늘날 사용하는 개발 환경에서는 이처럼 변수 이름에 범위를 명시할 필요 X)
private int **contextLength**;
private String **expected**;
private String **actual**;
private int **prefix**;
private int **suffix**;
조건을 캡슐화하라[G28]
가능하다면 표준 명명법을 사용하라[N3]
→ Compact 함수에서 사용하는 this.expected와 this.actual도 이미 지역변수가 있기 때문에 불편
( fExpected에서 f를 빼버리는 바람에 생긴 결과 )
⇒ 서로 다른 의미라면 이름은 명확하게 붙인다.
String **compactExpected** = compactString(**expected**);
String **compactActual** = compactString(**actual**);
부정 조건은 피하라[G29]
부정문은 긍정문보다 이해하기 약간 더 어려우므로 첫 문장 if를 긍정으로 만들어 조건문을 반전한다.
public String compact(String message) {
**if (canBeCompacted()) {**
findCommonPrefix();
findCommonSuffix();
String compactExpected = compactString(expected);
String compactActual = compactString(actual);
return Assert.format(message, compactExpected, compactActual);
**} else {**
return Assert.format(message, expected, actual);
**}**
}
**private boolean canBeCompacted() {
return expected != null && actual != null && !areStringsEqual();
}**
이름으로 부수 효과를 설명하라[N7]
∴ compact라는 이름을 붙이면 오류 점검이라는 부가 단계가 숨겨지는 것이다.
단순한 압축 문자열이 아닌 형식이 갖춰진 문자열을 반환하기에 실제로는 formatCompactedComparison이라는 이름이 적합하다.
인수를 고려하면 가독성이 훨씬 좋아진다.
**public String formatCompactedComparison(String message) {**
함수는 한 가지만 해야 한다[G30]
if 문 안에서 예상 문자열과 실제 문자열을 진짜로 압축한다.
이 부분을 빼내 compactExpectedAndActual이라는 메서드로 만들고 형식을 맞추는 작업은 formatCompactedComparison에게 맡긴다.
→ compacteExpectedAndActual은 압축만 수행한다.
⇒ 각 함수는 하나의 기능만을 수행하게 됨
...
**private String compactExpected;
private String compactActual;**
...
public String formatCompactedComparison(String message) {
if (canBeCompacted()) {
**compactExpectedAndActual();**
return Assert.format(message, compactExpected, compactActual);
} else {
return Assert.format(message, expected, actual);
}
}
**private compactExpectedAndActual() {
findCommonPrefix();
findCommonSuffix();
compactExpected = compactString(expected);
compactActual = compactString(actual);
}**