例項帶你掌握如何分解條件表示式
阿新 • • 發佈:2022-04-06
摘要:大型函式本身就會降低程式碼可讀性,而條件邏輯則會使程式碼更難閱讀。
本文分享自華為雲社群《分解條件表示式(Decompose Conditional)》,作者: JavaEdge 。
1 動機
程式中複雜的條件邏輯導致我必須編寫程式碼來檢查不同的條件分支,根據不同條件做不同的事,然後,我很快就會得到一個相當長的函式。大型函式本身就會降低程式碼可讀性,而條件邏輯則會使程式碼更難閱讀。
帶有複雜條件邏輯的函式中,程式碼(包括檢查條件分支的程式碼和真正實現功能的程式碼)會告訴我發生的事,但常常讓我弄不清楚為什麼會發生這樣的事, 說明程式碼可讀性的確大大降低。
和任何大塊頭程式碼一樣,我可以將它分解為多個獨立的函式,根據每個小塊程式碼的用途,命名分解而得的新函式,並將原函式中對應的程式碼改為呼叫新函式,從而更清楚表達意圖。
對於條件邏輯,將每個分支條件分解成新函式還能帶來更多好處:可突出條件邏輯,更清楚地表明每個分支的作用,並且突出每個分支的原因。 本重構手法其實只是【提煉函式】的一個應用場景。但我要強調該場景,因為我發現它經常會帶來很大價值。
2 做法
對條件判斷和每個條件分支分別運用【提煉函式】手法。
3 案例
假設我要計算購買某樣商品的總價(總價=數量×單價),而這個商品在冬季和夏季的單價不同:
public static void price(LocalDate aDate, Plan plan, Long quantity) { if (!aDate.isBefore(plan.summerStart) && !aDate.isAfter(plan.summerEnd)) { charge= quantity * plan.summerRate; } else { charge = quantity * plan.regularRate + plan.regularServiceCharge; } }
將條件判斷提煉到一個獨立方法:
/** * 在冬季和夏季的單價不同 */ public static void price(LocalDate aDate, Plan plan, Long quantity) { if (summer(aDate, plan)) { charge = quantity * plan.summerRate; }else { charge = quantity * plan.regularRate + plan.regularServiceCharge; } } public static boolean summer(LocalDate aDate, Plan plan) { return !aDate.isBefore(plan.summerStart) && !aDate.isAfter(plan.summerEnd); }
然後提煉條件判斷為真的分支:
/** * 在冬季和夏季的單價不同 */ public static void price(LocalDate aDate, Plan plan, Long quantity) { if (summer(aDate, plan)) { charge = summerCharge(plan, quantity); } else { charge = quantity * plan.regularRate + plan.regularServiceCharge; } } /** * 提煉條件判斷為真的分支 */ public static Long summerCharge(Plan plan, Long quantity) { return quantity * plan.summerRate; } }
最後提煉條件判斷為假的分支:
/** * 在冬季和夏季的單價不同 */ public static void price(LocalDate aDate, Plan plan, Long quantity) { if (summer(aDate, plan)) { charge = summerCharge(plan, quantity); } else { charge = regularCharge(plan, quantity); } } private static Long regularCharge(Plan plan, Long quantity) { return quantity * plan.regularRate + plan.regularServiceCharge; }
提煉完成後,我喜歡用三元運算子重新安排條件語句。
/** * 在冬季和夏季的單價不同 */ public static void price(LocalDate aDate, Plan plan, Long quantity) { charge = summer(aDate, plan) ? summerCharge(plan, quantity) : regularCharge(plan, quantity); }