목적과 구현을 분리한다는 기준
코드를 보고 무슨 일을 하는지 파악하는데 한참이 걸린다면,
그 부분을 함수로 추출한 뒤 “무슨 일”에 걸맞는 이름을 짓는다.
어떻게
가 아닌 무엇을
하는지가 드러나야 한다.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 function
const 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]
}