10.3 중첩 조건문을 보호 구문으로 바꾸기 (Replace Nested Conditional with Guard Clauses)
리팩터링 전
function getPayAmount() {
let result;
if (isDead)
result = deadAmount();
else {
if (isSeparated)
result = separatedAmount();
else {
if (isRetired)
result = retiredAmount();
else
result = normalPayAmount();
}
}
return result;
}
리팩터링 후
function getPayAmount() {
if (isDead) return deadAmount();
if (isSeparated) return separatedAmount();
if (isRetired) return retiredAmount();
return normalPayAmount();
}
🧷 배경
조건문에서 한쪽만 정상이라면 비정상 조건을 if에서 검사한 다음, 조건이 참이면(비정상이면) 함수에서 빠져나오는 형태를 보호 구문이라고 한다. 보호 구문은 이건 이 함수의 핵심이 아니다 라는 의미를 담고 있어 함수의 핵심 의도를 부각한다.
조건문에서 반환점이 하나일 때 함수의 로직이 더 명백해진다.
🧷 절차
교체해야 할 조건 중 가장 바깥 것을 선택하여 보호 구문으로 바꾼다.
테스트한다.
1~2 과정을 필요한 만큼 반복한다.
모든 보호 구문이 같은 결과를 반환한다면 보호 구문들의 조건식을 통합한다.
🧷 예시
🧷 리팩터링 전
function payAmount(employee) {
let result;
if (employee.isSeparated) {
// 퇴사한 직원인가?
result = { amount: 0, reasonCode: 'SEP' };
} else {
if (employee.isRetired) {
// 은퇴한 직원인가?
result = { amount: 0, reasonCode: 'RET' };
} else {
// 급여 계산 로직
lorem.ipsum(dolor.sitAmet);
consectetur(adipiscing).edit();
sed.do.eusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
ut.enim.ad(minim.veniam);
result = someFinalComputation();
}
}
}
🧷 리팩터링 후
function payAmount(employee) {
if (employee.isSeparated) return { amount: 0, reasonCode: 'SEP' };
if (employee.isRetired) return { amount: 0, reasonCode: 'RET' };
// 급여 계산 로직
lorem.ipsum(dolor.sitAmet);
consectetur(adipiscing).edit();
sed.do.eusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
ut.enim.ad(minim.veniam);
return someFinalComputation();
}
🧷 예시: 조건 반대로 만들기
🧷 리팩터링 전
function adjustedCapital(anInstrument) {
let result = 0;
if (anInstrument.capital > 0) {
if (anInstrument.interestRate > 0 && anInstrument.duration > 0) {
result = (anInstrument.income / anInstrument.duration) * anInstrument.adjustmentFactor;
}
}
return result;
}