임시 변수 제거를 계속해보자. 성능과 리팩터링의 관계는 어떨까?
function statement(invoice, plays) {
let totalAmount = 0;
let volumeCredits = 0;
let result = '청구 내역 (고객명: ${invoice.customers})\n';
for (let perf of invoice.performances) {
volumeCredits += volumeCreditsFor(perf);
//청구 내역을 출력한다.
result += '${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience}석)\n';
totalAmount += amountFor(perf);
}
result += '총액: ${usd(totalAmount)}\n';
result += '적립 포인트: ${volumeCredits)점 \n';
";
return result;
function amountFor(aPerformance) {
let result = 0;
switch (playFor(aPerformance).type) {
case "tragedy": // 비극
result = 40000;
if (aPerformance.audience > 30) {
result += 1000 * (aPerformance.audience - 30);
}
break;
case "comedy": // 희극
result = 30000;
if (aPerformance.audience > 20) {
result += 10000 + 500 * (aPerformance.audience - 20);
}
result += 300 * aPerformance.audience;
break;
default:
throw new Error('알 수 없는 장르: ${playFor(aPerformance).type}');
}
return result;
}
function playFor(aPerformance) {
return plays[aPerformance.playID];
}
function usd(aNumber) {
return new Intl.NumberFormat("en-Us", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2
}).format(aNumber / 100);
}
}
volumeCredits
변수는 반복문을 돌며 값을 누적하고 있다. 조금더 까다로운 경우다.volumeCredits
을 더하는 부분을 빼자.function statement(invoice, plays) {
let totalAmount = 0;
let volumeCredits = 0;
let result = '청구 내역 (고객명: ${invoice.customers})\n';
for (let perf of invoice.performances) {
//청구 내역을 출력한다.
result += '${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience}석)\n';
totalAmount += amountFor(perf);
}
for (let perf of invoice.performances) {
volumeCredits += volumeCreditsFor(perf);
}
result += '총액: ${usd(totalAmount)}\n';
result += '적립 포인트: ${volumeCredits)점 \n';
";
return result;
}
volumeCredits
변수를 반복문 앞으로 옮겨보자.function statement(invoice, plays) {
let totalAmount = 0;
let result = '청구 내역 (고객명: ${invoice.customers})\n';
for (let perf of invoice.performances) {
//청구 내역을 출력한다.
result += '${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience}석)\n';
totalAmount += amountFor(perf);
}
let volumeCredits = 0;
for (let perf of invoice.performances) {
volumeCredits += volumeCreditsFor(perf);
}
result += '총액: ${usd(totalAmount)}\n';
result += '적립 포인트: ${volumeCredits)점 \n';
";
return result;
}
volumeCredits
변수 역시 임시 변수이다. 이를 제거하기 위해 함수 추출하기를 적용해보자.function statement(invoice, plays) {
let totalAmount = 0;
let result = '청구 내역 (고객명: ${invoice.customers})\n';
for (let perf of invoice.performances) {
//청구 내역을 출력한다.
result += '${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience}석)\n';
totalAmount += amountFor(perf);
}
let volumeCredits = totalVolumeCredits();
result += '총액: ${usd(totalAmount)}\n';
result += '적립 포인트: ${volumeCredits)점 \n';
";
return result;
function totalVolumeCredits() {
let volumeCredits = 0;
for (let perf of invoice.performances) {
volumeCredits += volumeCreditsFor(perf);
}
return volumeCredits;
}
}
volumeCredits
)를 제거하기 위해 변수 인라인하기를 적용해보자.function statement(invoice, plays) {
let totalAmount = 0;
let result = '청구 내역 (고객명: ${invoice.customers})\n';
for (let perf of invoice.performances) {
//청구 내역을 출력한다.
result += '${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience}석)\n';
totalAmount += amountFor(perf);
}
result += '총액: ${usd(totalAmount)}\n';
result += '적립 포인트: ${totalVolumeCredits())점 \n';
";
return result;
...
function totalVolumeCredits() {
let volumeCredits = 0;
for (let perf of invoice.performances) {
volumeCredits += volumeCreditsFor(perf);
}
return volumeCredits;
}
}
리팩터링으로 인한 성능 문제는 특별한 경우가 아니라면 일단 무시해라.
function statement(invoice, plays) {
let result = '청구 내역 (고객명: ${invoice.customers})\n';
for (let perf of invoice.performances) {
//청구 내역을 출력한다.
result += '${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience}석)\n';
}
result += '총액: ${usd(appleSauce())}\n';
result += '적립 포인트: ${totalVolumeCredits())점 \n';
";
return result;
...
function appleSauce() {
let totalAmount = 0;
for (let perf of invoice.performances) {
totalAmount += amountFor(perf);
}
return totalAmount;
}
}
function statement(invoice, plays) {
let result = '청구 내역 (고객명: ${invoice.customers})\n';
for (let perf of invoice.performances) {
//청구 내역을 출력한다.
result += '${playFor(perf).name}: ${usd(amountFor(perf))} (${perf.audience}석)\n';
}
result += '총액: ${usd(totalAmount())}\n';
result += '적립 포인트: ${totalVolumeCredits())점 \n';
";
return result;
}
function amountFor(aPerformance) {
let result = 0;
switch (playFor(aPerformance).type) {
case "tragedy": // 비극
result = 40000;
if (aPerformance.audience > 30) {
result += 1000 * (aPerformance.audience - 30);
}
break;
case "comedy": // 희극
result = 30000;
if (aPerformance.audience > 20) {
result += 10000 + 500 * (aPerformance.audience - 20);
}
result += 300 * aPerformance.audience;
break;
default:
throw new Error('알 수 없는 장르: ${playFor(aPerformance).type}');
}
return result;
function playFor(aPerformance) {
return plays[aPerformance.playID];
}
function usd(aNumber) {
return new Intl.NumberFormat("en-Us", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2
}).format(aNumber / 100);
}
function totalVolumeCredits() {
let volumeCredits = 0;
for (let perf of invoice.performances) {
volumeCredits += volumeCreditsFor(perf);
}
return volumeCredits;
}
function totalAmount() {
let totalAmount = 0;
for (let perf of invoice.performances) {
totalAmount += amountFor(perf);
}
return totalAmount;
}
}