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();
}배경
- 조건문이 사용되는 경우는 두가지다.
- 참이거나 거짓인 경우 모두가 정상동작으로 이어져야 하는 경우
- 참인 경우만 의미가 있고, 그렇지 않은 경우 예외 처리를 해야 하는 경우
- 위 두가지 경우는 의도하는 바가 다르니, 이 의도가 형태로 드러나는 것이 옳다.
swift에서는guard구문을 사용한다.
절차
- 교체해야 할 조건 중 가장 바깥 것을 선택하여 보호 구문으로 바꾼다.
- 테스트한다.
- 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).elit();
sed.do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
ut.enim.ad(minim.veniam);
result = someFinalComputation();
}
}
return result;
}- 도대체 뭘하는지 확연히 드러나지 않는다.
- 이 이유는 중첩된 조건들이 있기 때문이다.
- 잘 보면, 모든 조건이 거짓인 상황에 계산을 하고 있는 것을 알 수 있다.
function payAmount(employee) {
let result;
if (employee.isSeparated) return {amount: 0, reasonCode: "SEP"};
if (employee.isRetired) {
result = {amount: 0, reasonCode: "RET"};
}
else {
// 급여 계산 로직
lorem.ipsum(dolor.sitAmet);
consectetur(adipiscing).elit();
sed.do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
ut.enim.ad(minim.veniam);
result = someFinalComputation();
}
return result;
}- 일단 가장 처음에 만나는 조건에 대해
result에 담지 않고return시켰다. - 이런식으로 만나는 조건들에 대해 early return을 시키면, 코드가 보다 명확해진다.
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).elit();
sed.do.eiusmod = tempor.incididunt.ut(labore) && dolore(magna.aliqua);
ut.enim.ad(minim.veniam);
return someFinalComputation();
}