練習用的 REPL
function bookConcert(aCustomer, isPremium) {
if (isPremium) {
// logic for premium booking
} else {
// logic for regular booking
}
}
// possible usage
bookConcert(aCustomer, true);
bookConcert(aCustomer, CustomerType.PREMIUM);
bookConcert(aCustomer, "premium");
// how about this ?
premiumBookConcert(aCustomer);
先用 Decompose Conditional
把 if-else 區塊抽取出來。
function deliveryDate(anOrder, isRush) {
if (isRush) {
let deliveryTime;
if (["MA", "CT"].includes(anOrder.deliveryState)) deliveryTime = 1;
else if (["NY", "NH"].includes(anOrder.deliveryState)) deliveryTime = 2;
else deliveryTime = 3;
return anOrder.placedOn.plusDays(1 + deliveryTime);
} else {
let deliveryTime;
if (["MA", "CT", "NY"].includes(anOrder.deliveryState)) deliveryTime = 2;
else if (["ME", "NH"].includes(anOrder.deliveryState)) deliveryTime = 3;
else deliveryTime = 4;
return anOrder.placedOn.plusDays(2 + deliveryTime);
}
}
function deliveryDate(anOrder, isRush) {
if (isRush) return rushDeliveryDate(anOrder); // 把 flag 換成直接呼叫 function
else return regularDeliveryDate(anOrder); // 把 flag 換成直接呼叫 function
}
// 先做 decompose conditional,把 branch 分支拆出去
function rushDeliveryDate(anOrder) {
let deliveryTime;
if (["MA", "CT"].includes(anOrder.deliveryState)) deliveryTime = 1;
else if (["NY", "NH"].includes(anOrder.deliveryState)) deliveryTime = 2;
else deliveryTime = 3;
return anOrder.placedOn.plusDays(1 + deliveryTime);
}
function regularDeliveryDate(anOrder) {
let deliveryTime;
if (["MA", "CT", "NY"].includes(anOrder.deliveryState)) deliveryTime = 2;
else if (["ME", "NH"].includes(anOrder.deliveryState)) deliveryTime = 3;
else deliveryTime = 4;
return anOrder.placedOn.plusDays(2 + deliveryTime);
}
然後就可以更改呼叫端的程式。
// 原本的 caller
aShipment.deliveryDate = deliveryDate(anOrder, true);
// 可以改成以下形式
aShipment.deliveryDate = rushDeliveryDate(anOrder);
// 保留這個 function 是要讓還沒改好的 caller 不要壞掉
function deliveryDate(anOrder, isRush) {
if (isRush) return rushDeliveryDate(anOrder);
else return regularDeliveryDate(anOrder);
}
function rushDeliveryDate(anOrder) {
let deliveryTime;
if (["MA", "CT"].includes(anOrder.deliveryState)) deliveryTime = 1;
else if (["NY", "NH"].includes(anOrder.deliveryState)) deliveryTime = 2;
else deliveryTime = 3;
return anOrder.placedOn.plusDays(1 + deliveryTime);
}
function regularDeliveryDate(anOrder) {
let deliveryTime;
if (["MA", "CT", "NY"].includes(anOrder.deliveryState)) deliveryTime = 2;
else if (["ME", "NH"].includes(anOrder.deliveryState)) deliveryTime = 3;
else deliveryTime = 4;
return anOrder.placedOn.plusDays(2 + deliveryTime);
}
有時候,實在太複雜了,只好先包起來,下次再行梳理。
function deliveryDate(anOrder, isRush) {
let result;
let deliveryTime;
if (anOrder.deliveryState === "MA" || anOrder.deliveryState === "CT")
deliveryTime = isRush ? 1 : 2;
else if (anOrder.deliveryState === "NY" || anOrder.deliveryState === "NH") {
deliveryTime = 2;
if (anOrder.deliveryState === "NH" && !isRush)
deliveryTime = 3;
} else if (isRush)
deliveryTime = 3;
else if (anOrder.deliveryState === "ME")
deliveryTime = 3;
else
deliveryTime = 4;
result = anOrder.placedOn.plusDays(2 + deliveryTime);
if (isRush) result = result.minusDays(1);
return result;
}
// 只好包起來,眼不見為淨
// 或是下次需要調整 logic 時再行梳理
function rushDeliveryDate (anOrder) {return deliveryDate(anOrder, true);}
function regularDeliveryDate(anOrder) {return deliveryDate(anOrder, false);}