01.리펙터링 첫 번째 예시

'프로그램이 새로운 기능을 추가하기에 편한 구조가 아니라면, 먼저 기능을 추가하기 쉬운 형태로 리팩터링하고 나서 원하는 기능을 추가하자.'
  • 여러 함수와 프로그램 요소로 재구성

리팩터링의 첫 단계

'리팩터링하기 전에 제대로 된 테스트부터 마련한다. 테스트는 반드시 자가진단하도록 만든다.'
'리팩터링은 프로그램 수정을 작은 단계로 나눠 진행한다. 그래서 중간에 실수하더라도 버그를 쉽게 찾을 수 있다.'
'컴퓨터가 이해하는 코드는 바보도 작성할 수 있다. 사람이 이해하도록 작성하는 프로그래머가 진정한 실력자다.'
  • 조금씩 변경하고 매번 테스트하는 것은 리팩터링 절차의 핵심이다. (컴파일-테스트-커밋)

  • 임시 변수는 자신이 속한 루틴에서만 의미가 있어서 루틴이 길고 복잡해진다. 그러므로 함수로 추출해서 제거하는 것이 좋다.

  • 함수 추출 Example

    1. 반복문 쪼개기로 변수 값을 누적시키는 부분 분리

      function statment(invoice, plays) {
          // 일부 코드 생략
          
          let totalAmount = 0;
          let volumeCredits = 0;
          for (let perf of invoice.performances) {
              result += `${perf.play.name}: ${usd(perf.amount)} (${perf.audience} seats)\n`;
              totalAmount += amountFor(perf);
          }
          for (let perf of invoice.performances) { // 값 누적 로직을 별도 for 문으로 분리
              volumeCredits += volumeCreditsFor(perf);
          }
          result += `point: ${volumeCredits}점\n`
         	return result;
      }
    2. 문장 슬라이스하기로 변수 초기화 문장을 변수 값 누적 코드 바로 앞으로 옮기기

      function statment(invoice, plays) {
          // 일부 코드 생략
          
          let totalAmount = 0;
          for (let perf of invoice.performances) {
              result += `${perf.play.name}: ${usd(perf.amount)} (${perf.audience} seats)\n`;
              totalAmount += amountFor(perf);
          }
          
          let volumeCredits = 0; // 변수 선언(초기화)을 반복문 앞으로
          for (let perf of invoice.performances) {
              volumeCredits += volumeCreditsFor(perf);
          }
          result += `point: ${volumeCredits}점\n`
         	return result;
      }
    3. 함수 추출하기로 계산 부분을 별도 함수로 추출

      function statment(invoice, plays) {
          // 일부 코드 생략
          
          let totalAmount = 0;
          for (let perf of invoice.performances) {
              result += `${perf.play.name}: ${usd(perf.amount)} (${perf.audience} seats)\n`;
              totalAmount += amountFor(perf);
          }
          
          let volumeCredits = totalVolumeCredits(); // 값 계산 로직을 함수로 추출
          result += `point: ${volumeCredits}점\n`
         	return result;
      }
      
      function totalVolumeCredits() {
          let result = 0;
          for (let perf of invoice.performances) {
              result += volumeCreditsFor(perf);
          }
          return result;
      }
    4. 변수 인라인하기로 임시 변수 제거

      function statment(invoice, plays) {
          // 일부 코드 생략
      
          let totalAmount = 0;
          for (let perf of invoice.performances) {
              result += `${perf.play.name}: ${usd(perf.amount)} (${perf.audience} seats)\n`;
              totalAmount += amountFor(perf);
          }
          result += `point: ${totalVolumeCredits()}점\n` // 변수 인라인
         	return result;
      }
  • 적절한 이름의 작은 함수들로 만드는 방식을 선호하는 마틴 파울러의 방식을 따라해보자.

Result Code

plays.json

invoices.json

statement.js

  • 출력 구조 코드

createStatementData.js

  • 데이터 구조 코드

Last updated