✏️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. 테스트한다.

  3. 1~2 과정을 필요한 만큼 반복한다.

  4. 모든 보호 구문이 같은 결과를 반환한다면 보호 구문들의 조건식을 통합한다.

🧷 예시

🧷 리팩터링 전

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;
}

🧷 리팩터링 후

function adjustedCapital(anInstrument) {
  if (   anInstrument.capital        <= 0
      || anInstrument.interestRate   <= 0
      || anInstrument.duration       <= 0) return 0;
  return (anInstrument.income / anInstrument.duration * anInstrument.adjustmentFactor;
}

Last updated