Try   HackMD

Remove Flag Argument

練習用的 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);}