리팩터링 2판 1장 statement 중 2

Yeongjong Kim·2022년 1월 5일
0

본 글은 리팩터링 2판을 읽으며 생객했던 과정을 기록한 것입니다.

보면서 헷갈렸던 내용

  1. 42p에 "임시 변수는 자신이 속한 루틴에서만 의미가 있어서 루틴이 길고 복잡해지기 쉽다."는 말이 있다. 이어서 필자는 "format은 임시 변수에 함수를 대입한 형태인데, 나는 함수를 직접 선언해 사용하도록 바꾸는 편이다." 라고 말한다.
const format = new Intl.NumberForamt(...).format;

위 format 임시 변수에 담김 함수를 아래 처럼 함수화 했다.

function format (aNumber) {
  return new Intl.NumberForamt(...).format(aNumber);
}

여기서 드는 의문은 이렇게 바꾸는 것이 어떤 개선 효과가 있는가? 이다.

이 코드가 필자가 말한 이유로 리팩터링 하기에는 적절한 예제라고 생각이 들지 않았다. 하지만 나름의 이유를 유추해 보자면

  1. 함수화를 하게 되면 필자가 말한 루틴속의 코드량은 줄어들게 된다.
  2. 1번의 이유를 연장해보면 기능 단위 분리가 된다.
  3. 위와 같은 코드처럼 변수에 메서드를 할당하는 경우에는 변수가 함수인지를 확인해야 사용할 수 있다. 하지만 function을 사용해 함수로 선언해 버리면 이 그 format 식별자는 보자마자 함수임을 알 수 있다.

놀랐던 점 😮

반복문을 쪼개서 응집도를 높인다.

let volumeCredits = 0;

for (let perf of invoice.performances) {
  ...
  totalAmount += amountFor(perf);
  volumeCredits += volumeCreditsFor(perf);
}

result += `적립 포인트: ${volumeCredits}점₩n`;

function volumeCreditsFor(perf) {
  let volumeCredits = 0;
  volumeCredits += Math.max(perf.audience - 30, 0);
  if ("comedy" === playFor(perf).type) 
    volumeCredits += Math.floor(perf.audience / 5);
  return volumeCredits;
}

위 코드를 보면 어떤 생각이 드는가? for 반복문 내에서 volumeCredits 변수는 함수를 호출하여 값을 누적하고 있다. 함수가 추출되었기 때문에 기능적으로도 분리가 잘 돼있는 듯 하다.

하지만 여기서 더 응집도를 높일 수 있다. 바로 volumeCredits를 반복문에서 분리하여 새로운 반복문을 만들고 이 코드를 함수화 시키는 것이다.

// 제거 let volumeCredits = 0;

for (let perf of invoice.performances) {
  ...
  totalAmount += amountFor(perf);
  // 제거 volumeCredits += volumeCreditsFor(perf);
}

result += `적립 포인트: ${totalVolumeCredits()}점₩n`;

------------------------------------------------------
function totalVolumeCredits() {
  let volumeCredits = 0;
  for (let perf of invoice.performances) {
    volumeCredits += volumeCreditsFor(perf);
  }
}

function volumeCreditsFor(perf) {
  let volumeCredits = 0;
  volumeCredits += Math.max(perf.audience - 30, 0);
  if ("comedy" === playFor(perf).type) 
    volumeCredits += Math.floor(perf.audience / 5);
  return volumeCredits;
}

어떠한가? 반복문이 쪼개졌기 때문에 성능이 정말 미미하게 저하됐을 수는 있으나, 응집도가 높아졌고 때문에 추후 유지보수하기는 더 용이할 것으로 판단된다. 필자는 혹여나 성능에 영향을 미치더라도 리팩터링을 진행한다고 한다. 이유는 잘 다듬어진 코드가 성능 개선 작업에도 훨씬 수월하기 때문이다. 너무 멋있는 말이지 않은가? 이 과정에서 다시 이전 코드로 돌아갈 수 도 있지만 대체적으로는 추후 성능 개선에 들어가고 성공하여 깔끔한 코드와 더 빠른 프로젝트로 마무리 된다.

리펙터링 단계 정리해보기

  1. 반복문 쪼개기: volumeCredits를 누적하는 반복문을 분리한다.
  2. 문장 슬라이드하기: volumeCredits 선언문을 분리된 반복문 위(사용되는 부분의 시작점)으로 이동시킨다.
  3. 함수 추출하기: 1,2 번의 결과로 생성된 코드를 함수로 추출한다.
  4. 변수 인라인 하기: 이제 필요없어진 변수를 제거하고, 함수를 인라인으로 호출한다.

위 4단계를 요약하면 응집도를 높이고 응집된 코드를 함수화시켜 임시 변수 volumeCredits를 제거하는 동시에 인라인으로 호출한 것이다.

결론

우선 리팩터링으로 인한 성능 문제에 처할지라도, 우선 리팩터링을 마무리해보자. 그리고 나서 성능을 다시 개선키셔 보자.

profile
Front 💔 End

0개의 댓글