Split Phase

練習用的 REPL

計算價格、計算運費感覺是兩個階段。

function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; // 基本價格 const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; // 計算折扣 const shippingPerCase = (basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; // 每件運費 const shippingCost = quantity * shippingPerCase; // 總運費 const price = basePrice - discount + shippingCost; // 訂單最後價格 return price; }

先把計算運費的部分抽出來。

function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; const price = applyShipping(basePrice, shippingMethod, quantity, discount); return price; } // 先把運費計算的部分抽出來 function applyShipping(basePrice, shippingMethod, quantity, discount) { const shippingPerCase = (basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = quantity * shippingPerCase; const price = basePrice - discount + shippingCost; return price; }

parameter 好多,現實狀況下可能會更多。

function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; const priceData = {}; // 引入中介變數 const price = applyShipping(priceData, basePrice, shippingMethod, quantity, discount); return price; } // 傳入,但不使用 function applyShipping(priceData, basePrice, shippingMethod, quantity, discount) { const shippingPerCase = (basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = quantity * shippingPerCase; const price = basePrice - discount + shippingCost; return price; }

把參數一一收進 priceData,先收 basePrice。

function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; const priceData = {basePrice: basePrice}; // 把 basePrice 放進入 const price = applyShipping(priceData, shippingMethod, quantity, discount); // 就可以把 basePrice 刪掉了 return price; } function applyShipping(priceData, shippingMethod, quantity, discount) { const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = quantity * shippingPerCase; const price = priceData.basePrice - discount + shippingCost; return price; }

再收 quantity。

function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; const priceData = {basePrice: basePrice, quantity: quantity}; // 接著把 quantity 加入 const price = applyShipping(priceData, shippingMethod, discount); // 就可以把 quantity 刪掉了 return price; } function applyShipping(priceData, shippingMethod, discount) { const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = priceData.quantity * shippingPerCase; const price = priceData.basePrice - discount + shippingCost; return price; }

再收 discount。

function priceOrder(product, quantity, shippingMethod) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; const priceData = {basePrice: basePrice, quantity: quantity, discount:discount}; // 同樣把 discount 加上去 const price = applyShipping(priceData, shippingMethod); // 就可以把 discount 刪掉了 return price; } function applyShipping(priceData, shippingMethod) { const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = priceData.quantity * shippingPerCase; const price = priceData.basePrice - priceData.discount + shippingCost; return price; }

運費的部分處理好了,接下來是計算價格。

function priceOrder(product, quantity, shippingMethod) { const priceData = calculatePricingData(product, quantity); // 這地方就可以直接用 const price = applyShipping(priceData, shippingMethod); // 看起來直觀許多,也不用理會計算細節 return price; } // 然後把這部分抽出來變成 function function calculatePricingData(product, quantity) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; return {basePrice: basePrice, quantity: quantity, discount:discount}; } function applyShipping(priceData, shippingMethod) { const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = priceData.quantity * shippingPerCase; const price = priceData.basePrice - priceData.discount + shippingCost; return price; }

兩階段計算大致完成。

function priceOrder(product, quantity, shippingMethod) { const priceData = calculatePricingData(product, quantity); return applyShipping(priceData, shippingMethod); // 多個 price 有點多餘,刪除 } function calculatePricingData(product, quantity) { const basePrice = product.basePrice * quantity; const discount = Math.max(quantity - product.discountThreshold, 0) * product.basePrice * product.discountRate; return {basePrice: basePrice, quantity: quantity, discount:discount}; } function applyShipping(priceData, shippingMethod) { const shippingPerCase = (priceData.basePrice > shippingMethod.discountThreshold) ? shippingMethod.discountedFee : shippingMethod.feePerCase; const shippingCost = priceData.quantity * shippingPerCase; return priceData.basePrice - priceData.discount + shippingCost; // 多個 price 有點多餘,刪除 }