하위 계층에는 없는 특성이나 행동이
상위 계층(전체 구조)에서 자발적으로 돌연히 출연하는 현상.
단순한 4가지를 반복하다보면 전체적으로 깨끗한 코드가 만들어진다.
모든 테스트를 실행한다.
중복을 없앤다.
프로그래머 의도를 표현한다.
클래스와 메서드 수를 최소로 줄인다 ⇒ 실용적 관점에서 타협한다.
int size() {}
boolean isEmpty{}
// 각 메서드를 따로 구현하는 방법도 있지만, 중복을 없애기 위해 서로 호출하도록 한다.
boolean isEmpty() {
return this.size() == 0;
}
public void scaleToOneDimension(float desireDimension, float imageDimension) {
if (Math.abs(desiredDimension - imageDimension) < errorThreshold)
return;
float scalingFactor = desiredDimension / imageDimension;
scalingFactor = (floa)(Math.floor(scalingFactor * 100) * 0.01f);
RenderedOpnewImage = ImageUtilities.getScaledImage(image, scalingFactor, scalingFactor);
image.dispose();
System.gc();
image = newImage;
}
public synchronized voi drotete(int degrees) {
RenderedOpnewImage = ImageUtilities.getRotetedImage(image, degrees);
image.dispose();
System.gc();
image = newImage;
}
중복된 코드를 별도의 메서드로 분리한다.
public void scaleToOneDimension(float desireDimension, float imageDimension) {
if (Math.abs(desiredDimension - imageDimension) < errorThreshold)
return;
float scalingFactor = desiredDimension / imageDimension;
scalingFactor = (floa)(Math.floor(scalingFactor * 100) * 0.01f);
replaceImage(ImageUtilities.getScaledImage(image, scalingFactor, scalingFactor));
}
public synchronized voi drotete(int degrees) {
replaceImage(ImageUtilities.getScaledImage(image, scalingFactor, scalingFactor));
}
private void replaceImage(RenderedOpnewImage) {
image.dispose();
System.gc();
image = newImage;
}
scaleToOneDimension, rotate와 replaceImage의 목적이 달라졌다.
별도의 클래스로 분리하면 추후 재활용성이 높아진다.
하위 클래스에서 자신에 맞게 세부 알고리즘을 정의한다.
DailyRoutine - 알고리즘
getUp 등 메서드 - 알고리즘의 각 단계
public class VacationPolicy {
public void accrueUSDDivisionVacation() {
// 지금까지 근무한 시간을 바탕으로 휴가 일수를 계산하는 코드
// ...
// 휴가 일수가 미국 최소 법정 일수를 만족하는지 확인하는 코드
// ...
// 휴가 일수를 급여 대장에 적용하는 코드
}
public void accrueEUDivisionVacation() {
// 지금까지 근무한 시간을 바탕으로 휴가 일수를 계산하는 코드
// ...
// 휴가 일수가 유렵연합 최소 법정 일수를 만족하는지 확인하는 코드
// ...
// 휴가 일수를 급여 대장에 적용하는 코드
}
}
최소 법정 일수를 계산하는 코드를 제외하면 두 메서드는 거의 동일하다.
중복을 줄이기 위해 템플릿 메서드 패턴을 적용한다면?
abstract public class VacationPolicy {
public void accrueVacation() {
calculateBseVacationHours();
alterForLegaMinimums();
applyToPayroll();
}
private void calculateBaseVacationHours() { /* ... */ };
abstract protected void alterForLegalMinimums();
private void applyToPayroll() { /* ... */ };
}
public class USVacationPolicy extends VacationPolicy {
@Override protected void alterForLegalMinimums() {
// 미국 최소 법정 일수를 사용한다.
}
}
public class EUVacationPolicy extends VacationPolicy {
@Override protected void alterForLegalMinimums() {
// 유럽연합 최소 법정 일수를 사용한다.
}
}
해당 포스팅은 제로 베이스 클린코드 한달한권을 수강 후 정리한 내용입니다.