๋ฆฌํฉํ ๋ง 1์ฅ์ ์์ํด๋ณธ๋ค.
๋ค์ด๊ฐ๋ฉด์
- ์์๊ฐ ๋จผ์ ๋์จ๋ค. ๋ฆฌํฉํฐ๋ง์ด ๋ญ์ง ์๋ ค์ฃผ๋ ๋จ๊ณ์ด๋ค.
- ์ด ์ฑ ์ ๋ฆฌํฉํฐ๋ง์ด ๋ฌด์์ธ์ง ์๋ ค์ฃผ๊ณ , ์ด๋ฅผ ๊ฐ์ฒด์งํฅ ๋ฐฉ์์ผ๋ก ๊ฐ์ ํ๋ ๊ฒ์ ์๊ฐํ๋ค.
- ๊ฐ์ฅ ํต์ฌ์ธ ๋ถ๋ถ์ ๋ค์ ์นดํ๋ก๊ทธ์ด๋ค. ์์๋ก ์ฐพ์๋ณด๋ฉด์ ์ ์ฉํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํด๋ผ. (๋ง์น ๋์์ธ ํจํด ๊ฐ๋ค)
- martin-fowler-refactoring-2nd์ ์์ค๊ฐ ์๋ค.
- ๊ฐ๋ ์ ์ดํดํด์ผ ์ฒํ ์ํฉ์ ์ ์ฉํ ์ ์๋ค.
์, ์์ํด๋ณด์.
function statement(invoice, plays) {
let totalAmount = 0;
let volumeCredits = 0;
let result = '์ฒญ๊ตฌ ๋ด์ญ (๊ณ ๊ฐ๋ช
: sfinvoice.customers) \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];
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 += 10000 + 500 * (perf.audience - 20);
}
thisAmount += 300 * perf.audience;
break;
default:
throw new Error('์ ์ ์๋ ์ฅ๋ฅด: sfplay.typer');
}
//ํฌ์ธํธ๋ฅผ ์ ๋ฆฝํ๋ค.
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;
}
์์ ํ๋ก๊ทธ๋จ์ ๋ณธ ์๊ฐ
- ํ ํจ์๊ฐ 50์ค์ด ๋์ด๊ฐ๊ณ , ์ถ์ํ๊ฐ ์๋ ์ฝ๋๊ฐ ์๋ค๊ณ ํ์.
- ์ฝ๋๊ฐ ๊ต์ฅํ ์ง์ ๋ถํ๋ค.
- ๊ทธ๋ฐ๋ฐ ์ง์ ๋ถํ๋ค๊ณ ๊ณ ์น๋ค๋ ๊ฒ์ ๋น์์ฑ์ด ์ถฉ๋ถํ ๊น?
- ์ฌ์ค ์ปดํ์ผ๋ฌ ์ ์ฅ์์๋ ๋ณ ์ค์ํ๊ฒ ์๋๋ค.
- ํ์ง๋ง ์ฐ๋ฆฌ๋ ์ฌ๋๊ณผ ํจ๊ป ์ผํ๋ค.
- ์ฌ๋์ ์ฝ๋์ ๋ฏธ์ ์ํ์ ๋ฏผ๊ฐํ๋ค.
ํ๋ก๊ทธ๋จ์ด ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ์ ํธํ ๊ตฌ์กฐ๊ฐ ์๋๋ผ๋ฉด, ๋จผ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ ์ฌ์ด ์ํ๋ก ๋ฆฌํฉํฐ๋งํ๊ณ ๋์ ์ํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค.
๋ฆฌํฉํฐ๋ง์ ์ฒซ ๋จ๊ณ
- ํ ์คํธ ์ฝ๋๋ค ๋ถํฐ ๋ง๋ จํ๋ค.
- ์ด๋ ๊ต์ฅํ ์ค์ํ๋ค.
- ์ฌ๋์ ๋๊ตฌ๋ ์ค์ํ ์ ์๋ค.
statement
ํจ์๋ฅผ ๋ณด๋ฉด, ๊ฒฐ๊ตญ ๊ณต์ฐ๋ก ์ฒญ๊ตฌ์๋ฅผ ๋ง๋๋ ์์ ์ด๋ค.- ์ด๋ฐ ๊ฒฝ์ฐ ๊ฒฐ๊ณผ๊ฐ์ ๋ฏธ๋ฆฌ ๋ช๊ฐ ์์ฑํด๋๊ณ (json) ํ ์คํธ ํ๋ ์์ํฌ๋ก ๋จ์ถํค ํ๋๋ก ๋์ํ ์ ์๊ฒ ์ค์ ํ์.
๋ฆฌํฉํฐ๋งํ๊ธฐ ์ ์, ์ ๋๋ก ๋ ํ ์คํธ๋ถํฐ ๋ง๋ จํ๋ค. ํ ์คํธ๋ ๋ฐ๋์ ์๊ฐ์ง๋จํ๋๋ก ๋ง๋ ๋ค.
statement ํจ์ ์ชผ๊ฐ๊ธฐ
- ์ผ๋จ
statement
ํจ์๋ฅผ ๋ฆฌํฉํฐ๋ง ํด๋ณด์. - ์ด๋ ๊ฒ ๊ธด ํจ์์ ๊ฒฝ์ฐ์๋ ์ ์ฒด์ ๋์์ ๊ฐ๊ฐ์ ๋ถ๋ถ์ผ๋ก ๋๋ ์ ์๋ ์ง์ ์ ์ฐพ๋๋ค.
- ์ค๊ฐ ๋ถ๋ถ์
switch
๋ฌธ์ ๋ณด์.
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 += 10000 + 500 * (perf.audience - 20);
}
thisAmount += 300 * perf.audience;
break;
default:
throw new Error('์ ์ ์๋ ์ฅ๋ฅด: sfplay.typer');
}
- ํ ๋ฒ์ ๊ณต์ฐ์ ๋ํ ์๊ธ์ ๊ณ์ฐํ๊ณ ์๋ค.
- ์ด๋ ์ฝ๋๋ฅผ ๋ถ์ํด์ ์ป์ ์ ๋ณด๋ค. ํ๋ฐ์ฑ์ด ๋๋ค.
- ๊ทธ๋ ๊ธฐ ๋๋ฌธ์, ํด๋น ์ฝ๋์ ์ถ๊ฐ์ ์ธ ์๋ฏธ๋ฅผ ๋ถ์ฌํ์ฌ ํจ์๋ก ๋นผ๋์.
function statement(invoice, plays) {
let totalAmount = 0;
let volumeCredits = 0;
let result = '์ฒญ๊ตฌ ๋ด์ญ (๊ณ ๊ฐ๋ช
: sfinvoice.customers) \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];
let thisAmount = 0;
thisAmount = amountFor(perf, play);
//ํฌ์ธํธ๋ฅผ ์ ๋ฆฝํ๋ค.
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;
func amountFor(pert, play) {
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 += 10000 + 500 * (perf.audience - 20);
}
thisAmount += 300 * perf.audience;
break;
default:
throw new Error('์ ์ ์๋ ์ฅ๋ฅด: sfplay.typer');
}
return thisAmount;
}
}
- ์ด๋ ๊ฒ ๋ฆฌํฉํ ๋ง ํ๋ค๋ฉด, ๋ฐ๋ก ์ปดํ์ผ ํ๋ค.
- ์กฐ๊ธ์ฉ ์์ ํ์ฌ ํผ๋๋ฐฑ ์ฃผ๊ธฐ๋ฅผ ์งง๊ฒ ๊ฐ์ ธ๊ฐ๋ ์ต๊ด์ด ์ค์ํ๋ ์ฌ์์ ํผํ๋ ๊ธธ์ด๋ค.
๋ฆฌํฉํ ๋ง์ ํ๋ก๊ทธ๋จ ์์ ์ ์์ ๋จ๊ณ๋ก ๋๋ ์งํํ๋ค.
- ์ด๋ ๊ฒ ์์ ํ๋ค๋ฉด, ๋ฐ๋ก ๋ก์ปฌ ๋ฒ์ ๊ด๋ฆฌ ์์คํ ์ ์ปค๋ฐํ๋ค.
- ํ๋์ ๋ฆฌํฉํฐ๋ง์ ๋ฌธ์ ์์ด ๋๋ผ ๋๋ง๋ค ์ปค๋ฐํ๋ค. ๊ทธ๋์ผ ์ด์ ์ํ๋ก ๋นจ๋ฆฌ ๋๋๋ฆด ์ ์๋ค.
- ์ผ๋จ ์ฎ๊ฒจ์ ๋์ํ๋ ๊ฒ์ ํ์ธํ์ผ๋ (์ด๋ถ๋ถ์ด ์ค์..), ๋ด๋ถ ํจ์์ ํํ์ ๋ณ๊ฒฝํด๋ณด์.
thisAmount
โresult
func amountFor(pert, play) {
let result = 0;
switch (play.type) {
case "tragedy": // ๋น๊ทน
result = 40000;
if (perf.audience > 30) {
result += 1000 * (perf.audience - 30);
}
break;
case "comedy": // ํฌ๊ทน
result = 30000;
if (perf.audience > 20) {
result += 10000 + 500 * (perf.audience - 20);
}
result += 300 * perf.audience;
break;
default:
throw new Error('์ ์ ์๋ ์ฅ๋ฅด: sfplay.typer');
}
return result;
}
- ๋ค์์ผ๋ก๋
aPerf
๊ฐ ์ ๋งคํ๋ ์ด๊ฑธaPerformance
๋ก ๋ฐ๊พธ์.
func amountFor(aPerformance, play) {
let result = 0;
switch (play.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('์ ์ ์๋ ์ฅ๋ฅด: sfplay.typer');
}
return result;
}
- ๋ถ์ ๊ด์ฌ๋ฅผ ๋ถ์ด๋ฉด ์ข๋ค๊ณ ํ๋ค.
- ๊ทธ๋ฐ๋ฐ ์ด ๋ถ๋ถ์ ์ธ์ด์ ์ฝ๋ ์ปจ๋ฒค์ ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ๋ฏ ํ๋ค.
์ฌ๋์ด ์ดํดํ๋๋ก ์์ฑํ๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ง์ ํ ์ค๋ ฅ์๋ค.