함수 인라인하기 Inline Function

0

리팩터링 카탈로그

목록 보기
2/10

배경


이 책은 목적이 분명히 드러나는 이름의 짤막한 함수를 이용하기를 권한다. 그래야 코드가 명료해지고 이해하기 쉬워지기 때문이다. 하지만 때로는 함수 본문이 이름만큼 명확한 경우도 잇다. 또는 함수 본문 코드를 이름만큼 깔끔하게 리펙터링 할 때도 있다. 이럴 때는 그 함수를 제거한다. 간첩 호출은 유용할 수도 있지만 쓸데없는 간접 호출은 거슬릴 뿐이다.

리펙터링 과정에서 잘못 추출된 함수들도 다시 인라인한다. 잘못 추출된 함수들을 원래 함수로 합친 다음, 필요하면 원하는 형태로 다시 추출하는 것이다.

간접 호출을 너무 과하게 쓰는 코드도 흔한 인라인 대상이다. 가령 다른 함수로 단순히 위임하기만 하는 함수들이 너무 많아서 위임 관계가 복잡하게 얽혀 있으면 인라인 해버린다. 그중 간접 호출을 유지하는 편이 나은 경우도 있겠지만, 모두 그렇지는 않을 것이다. 함수 인라인하기를 활용하면 유용한 것만 남기고 나머지는 제거할 수 있다.

절차


  1. 다형 메서드(polymonphic method)인지 확인한다.
  • 서브 클래스에서 오버라이드하는 메서드는 인라인하면 안 된다.
  1. 인라인할 함수를 호출하는 곳을 모두 찾는다.
  2. 각 호출문을 함수 본문으로 교체한다.
  3. 하나씩 교체할 때마다 테스트한다.
  • 인라인 작업을 한 번에 처리할 필요는 없다. 인라인하기가 까다로운 부분이 있다면 일단 남겨두고 여유가 생길 때마다 틈틈히 처리한다.
  1. 함수 정의(원래 함수)를 삭제한다.

예시


before

//case 1
function rating(aDriver) {
  return moreThanFiveLateDeliveries(aDriver) ? 2 : 1;
}

function moreThanFiveLateDeliveries(aDriver) {
  return aDriver.numberOfLateDeliveries > 5;
}

//case 2
function reportLines(aCustomer) {
  const lines = [];
  gatherCustomerData(lines, aCustomer);
  return lines;
}

function gatherCustomerData(out, aCustomer) {
  out.push(["name", aCustomer.name]);
  out.push(["location", aCustomer.location]);
}

after

//case 1
function rating(aDriver) {
  return aDriver.numberOfLateDeliveries > 5 ? 2 : 1;
}

//case 2
function reportLines(aCustomer) {
  const lines = [];
  out.push(["name", aCustomer.name]);
  out.push(["location", aCustomer.location]);
  return lines;
}

여기서 핵심은 항상 단계를 잘게 나눠서 처리하는 데 있다. 평소 함수를 작게 만들어뒀다면 인라인을 단번에 처리할 수 있을 때가 많다. 그러다 상황이 복잡해지면 다시 한 번에 한 문장씩 처리한다. 한 문장을 처리하는 데도 얼마든지 복잡해질 수 있다. 이럴 때는 더 정교한 리펙터링 문장을 호출한 곳으로 옮기기로 작업을 더 잘게 나눈다. 어느 정도 자신감이 붙으면 다시 작업을 크게 묶어서 처리한다. 그러다 테스트가 실패하면 가장 최근의 정상 코드로 돌아온 다음, 단계를 잘게 나눠서 다시 리펙터링한다.

참조


마틴 파울러 저 리팩터링 2판

0개의 댓글