✏️1.6 계산 단계와 포맷팅 단계 분리하기

목표

statement()의 HTML 버전 만드는 작업

단계 쪼개기

  1. statement()에 필요한 데이터 처리하기 → 두 번째 단계로 전달할 중간 데이터 구조를 생성하는 것

  2. 앞서 처리한 결과를 텍스트나 HTML로 표현하기

0. 단계를 쪼개려면 먼저 두 번째 단계가 될 코드들을 함수 추출하기로 뽑아내야 한다. 현재 statement()의 본문 전체가 여기에 해당한다.

function statement(invoice, plays) {
  return renderPlainText(invoice, plays); // 본문 전체를 별도 함수로 추출
}

function renderPlainText(invoice, plays) {
  let result = `청구 내역(고객명): ${invocie.customer})\n`;
  
  for (let perf of invoice.performaces) {
    // 청구 내역을 출력한다.
    result += ` ${playFor(perf).name}: ${usd(amountFor(perf))} ($perf.audience}석)\n`;
  
  result += `총액: ${usd(totalAmount())}\n`;	
  result += `적립 포인트: ${totalVolumeCredits()}점\n`;
  return result;
  
  function totalAmount() {...}
  function totalVolumeCredits() {...}
  function usd(aNumber) {...}
  function volumeCreditsFor(aPerformance) {...}
  function playFor(aPerformance) {...}
  function amountFor(aPerformance) {...}
}

항상 수정한 코드는 컴파일-테스트-커밋한다.

다음으로 두 단계 사이의 중간 데이터 구조 역할을 할 객체를 만들어서 renderPlainText()에 인수로 전달한다.

renderPlainText()의 다른 두 인수(invoice와 plays)를 살펴보자. 이 인수들을 통해 전달되는 데이터를 중간 데이터 구조로 옮기면, 계산 관련 코드는 statement() 함수로 모으고 renderPlainText()는 data 매개변수로 전달된 데이터만 처리하게 만들 수 있다.

가장 먼저 고객 정보부터 중간 데이터 구조로 옮긴다.

같은 방식으로 공연 정보까지 중간 데이터 구조로 옮기고 나면 renderPlainText()invoice 매개변수를 삭제해도 된다.

연극 제목도 중간 데이터 구조에서 가져오도록 한다. 이를 위해 공연 정보 레코드에 연극 데이터를 추가해야 한다.

공연 객체를 복사만 했지만(함수로 건넨 데이터를 수정하기 싫어서) 잠시 후 새로 만든 레코드에 데이터를 채울 것이다. 가변 데이터는 금방 상하기 때문에 데이터를 최대한 불변(immutable)처럼 취급한다.

실제로 데이터를 담아보자

함수 옮기기를 적용하여 playFor() 함수를 statement()로 옮긴다

renderPlainText()안에서 playFor()를 호출하던 부분을 중간 데이터를 사용하도록 바꾼다.

amountFor()도 비슷한 방법으로 옮긴다.

적립 포인트 계산 부분을 옮긴다.

총합을 구하는 부분을 옮긴다.

totalAmount()totalVolumeCredits()를 직접 statementData 변수를 사용할 수도 있지만 저자는 매개변수로 전달하는 방식을 선호한다.

반복문을 파이프라인으로 바꾸기를 적용해보자

📍 첫 단계인 statement()에 필요한 데이터 처리에 해당하는 코드를 모두 별도 함수로 빼낸다.

두 단계가 명확히 분리 됐으니 각 코드를 별도 파일에 저장한다. 반환 결과를 저장할 변수의 이름도 바꿔준다.

⭐️ 마지막으로 컴파일-테스트-커밋하면 HTML 버전을 작성할 준비가 끝난다.

Last updated