Book | 리펙터링 2판 1.1 ~ 1.2장

sik2·2022년 7월 31일
0

리뷰

목록 보기
8/12

1.1 리펙터링 첫번째 예시

  • 연극을 외주로 받아서 공연하는 극단의 공연 관리 프로그램을 만든다고 가정하자.

  • 극단의 공연 장르는 비극, 희극 두 가지다

  • 공연료와 별개로 포인트를 지급해서 다음번 공연시 공연료를 할인받을 수 있다.

  • 공연할 연극의 정보를 JSON 으로 저장한다.

{
  "hamlet": { "name": "Hamlet", "type": "tragedy" },
  "as-like": { "name": "As You Like It", "type": "comedy" },
  "othello": { "name": "Othello", "type": "tragedy" }
}

공연료 청구서에 들어갈 데이터도 JSON으로 저장한다.

[
  {
    "customer": "BigCo",
    "performances": [
      { "playID": "hamlet", "audience": 55 },
      { "playID": "as-like", "audience": 35 },
      { "playID": "othello", "audience": 40 }
    ]
  }
]

공연료 청구서를 출력하는 코드는 다음과 같이 간단히 함수로 구현했다.

function statement(invoice, plays) {
  let totalAmount = 0;
  let volumeCredits = 0;
  let result = `청구 내역(고객명: ${invoice.customer})\n`;
  const format = new Intl.NumberFormat("en-US", {
    style: "currency",
    currency: "USD",
    minimumFractionDigits: 2
  }).format;

  for (let perf of invoice.performances) {
    const play = plays[perf.playID]; // object {name, type}
    let thisAmount = 0;
    switch (play.type) {
      case "tragedy": //비극
        thisAmount = 40000;
        if (perf.audience > 30) thisAmount += 1000 * (perf.audience - 30);
        break;
      case "comedy": //희극
        thisAmount = 30000;
        if (perf.audience > 20) thisAmount += 1000 + 500 * (perf.audience - 20);
        thisAmount += 300 * perf.audience;
        break;
      default:
        throw new Error(`알 수 없는 장르: ${play.type}`);
    }
    // 포인트를 적립한다.
    volumeCredits += Math.max(perf.audience - 30, 0);
    // 희극 관객 5명마다 추가 포인트를 제공한다.
    if ("comedy" === play.type) volumeCredits += Math.floor(perf.audience / 5);

    // 청구 내역을 출력한다.
    result += `${play.name}: ${format(thisAmount / 100)} (${
      perf.audience
    }석)\n`;
    totalAmount += thisAmount;
  }
  result += `총액: ${format(totalAmount / 100)}\n`;
  result += `적립 포인트: ${volumeCredits}점\n`;
  return result;
}

위 두가지 테스트 파일(JSON) 을 실행한 결과는 다음과 같다.

청구 내역 (고객명: BigCo)
Hamlet: $650.00(55석)
As You Like It: $580.00 (35석)
Othello: $500,00(40석)
총액: $1,730.00
적립 포인트: 47점

1.2 예시 프로그램을 본 소감

  • 일단은 동작하는데 문제가 없다. 때문에 코드를 수정을 해야하나 싶은 생각이 들 수 있다.

  • 하지만 설계가 나쁜 코드는 수정하기 어렵다. 즉, 추가 요구사항이 들어오면 골치아파진다.

    원하는 동작을 수행하도록 하기 위해 수정할 부분을 찾고, 기존코드와 잘 맞물려 작동하게 할 방법을 강구하기가 어렵기 때문이다.

    리펙토링을 하는 순서

  • 수백 줄 짜리 코드를 수정할 때면 프로그램의 작동 방식을 더 쉽게 파악할 수 있도록 코드를 여러 함수와 프로그램 요소로 재구성한다.

  • 프로그램의 구조가 빈약하다면 대체로 구조부터 바로잡은 뒤에 기능을 수정하는 편이 작업하기가 훨씬 수월하다.

    프로그램이 새로운 기능을 추가하기에 편한 구조가 아니라면, 먼저 기능을 추가하기 쉬운 형태로 리팩터링하고 나서 원하는 기능을 추가한다.

    수정할 부분 몇가지

  • 청구내역을 HTML로 출력하는 기능이 필요하다.

  • 청구결과에 문자열을 추가하는 문장 각각을 조건문으로 감싸야한다. 그러면 statement() 함수의 복잡도가 크게 증가한다.

  • 현재는 장르가 2가지로 정해져있지만 앞으로 장르는 계속해서 추가될 것이다. 이때도 statement() 함수를 수정해야한다.

  • 향후 statement() 확장성을 고려해보면 지금보다 수정이 용이한 설계로 바꿔야한다.

profile
기록

0개의 댓글