
목적과 구현을 분리한다는 기준
코드를 보고 무슨 일을 하는지 파악하는데 한참이 걸린다면,
그 부분을 함수로 추출한 뒤 “무슨 일”에 걸맞는 이름을 짓는다.
어떻게가 아닌 무엇을 하는지가 드러나야 한다.function printOwing(invoice) {
let outstanding = 0;
console.log("***********************");
console.log("******** 고객 채무 ******");
console.log("***********************");
// 미해결 채무(outstanding)를 계산한다.
for (const order of invoice.orders) {
outstanding += order.amount;
}
// 마감일(dueDate)을 기록한다.
const today = Clock.today;
invoice.duedate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
// 세부사항을 출력한다.
console.log(`고객명: ${invoice.customer}`);
console.log(`채무액: ${outstanding}`);
console.log(`고객명: ${invoice.dueDate.toLocaleDateString()}`);
}
function printOwing(invoice) {
printBanner();
const outstanding = calculateOutstaniding(invoice);
recordDueDate(invoice);
printDetails(invoice, outstanding);
}
function printBanner() {
console.log("***********************");
console.log("******** 고객 채무 ******");
console.log("***********************");
}
function calculateOutstaniding(invoice) {
let result = 0;
for (const order of invoice.orders) {
result += order.amount;
}
return result;
}
function recordDueDate(invoice) {
const today = Clock.today;
invoice.duedate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
}
function printDetails(invoice, outstanding) {
console.log(`고객명: ${invoice.customer}`);
console.log(`채무액: ${outstanding}`);
console.log(`고객명: ${invoice.dueDate.toLocaleDateString()}`);
}
function getRating(driver) {
return moreThanFiveLateDeliveries(driver) ? 2 : 1;
}
function moreThanFiveLateDeliveries(driver) {
return driver.numberOfLateDeliveries > 5;
}
function getRating(driver) {
return (driver.numberOfLateDeliveries > 5) ? 2 : 1;
}
return order.quantity * order.itemPrice -
Math.max(0, order.quantity - 500) * order.itemPrice * 0.05 +
Math.min(order.quantity * order.itemPrice * 0.1, 100);const basePrice = order.quantity * order.itemPrice;
const quantityDiscount = Math.max(0, order.quantity - 500) * order.itemPrice * 0.05;
const shipping = Math.min(basePrice * 0.1, 100);
return basePrice - quantityDiscount + shipping;let basePrice = order.basePrice;
return (basePrice > 1000);return order.basePrice > 1000;function circum(radius) {
return 2 * Math.PI * radius;
}function circumference(radius) {
return 2 * Math.PI * radius;
}레코드 캡슐화하기를 적용할지 고려해본다.let defaultOwner = {firstName: "Martin", lastName: "Fowler"};let defaultOwner = {firstName: "Martin", lastName: "Fowler"};
export function defaultOwner() { return defaultOwner; }
export function setDefaultOwner(arg) { defaultOwnerData = org; }명확한 프로그래밍의 핵심은 이름짓기다.
변수 캡슐화하기 를 고려한다.let a = height * width;let area = height * width;함수 선언 바꾸기 로 새 데이터 구조를 매개변수로 추가한다.function amountInvoiced(startDate, endDate) { ... }
function amountReceived(startDate, endDate) { ... }
function amountOverdue(startDate, endDate) { ... }function amountInvoiced(aDateRange) { ... }
function amountReceived(aDateRange) { ... }
function amountOverdue(aDateRange) { ... }매개변수 객체 만들기)function base(aReading) { ... }
function taxableCharge(aReading) { ... }
function calculateBaseCharge(aReading) { ... }class Reading {
base() { ... }
taxableCharge() { ... }
calculateBaseCharge() { ... }
}Combine Functions into Transform
function base(aReading) { ... }
function taxableCharge(aReading) { ... }function enrichReading(argReading) {
const aReading = _.cloneDeep(argReading);
aReading.baseCharge = base(aReading);
aReading.taxableCharge = taxableCharge(aReading);
return aReading;
}extract functionconst orderData = orderString.split(/\s/);
const productPrice = priceList[orderData[0].split("-")[1]];
const orderPrice = parseInt(orderData[1]) * productPrice;const orderRecord = parseOrder(order);
const orderPrice = price(orderRecord, priceList);
function parseOrder(aString) {
const values = aString.split(/\s+/);
return ({
productId: values[0].split("-")[1],
quantity: parseInt(values[1]),
});
}
function price(order, priceList) {
return order.quantity * priceList[order.productId]
}