重構 - 改善既有程式的設計 - Simplifying Conditional Expressions
April 19, 2020這篇文章討論《重構 - 改善既有程式的設計》裡的第九章 - Simplifying Conditional Expressions
主要會討論程式碼的壞味道中 沒有被提及的重構方法裡面有關於 簡化函式呼叫 的內容
圖片以及程式碼來源自重構 - 改善既有程式的設計
簡化條件式
Decompose Conditional
你有一個複雜的條件語句 就把那複雜的條件語句提煉出獨立函式
Consolidate Conditional Expression
你有一系列條件測試都得到相同結果 就可以把那些條件式提煉成獨立函式
Consolidate Duplicate Conditional Fragments
合併重複的條件片段
Remove Control Flag
控制旗標(control flag) 就是你常看到的 用以判斷何時停止條件檢查 的變數
比如說下面程式中的found
void checkSecurity(String[] people) {
boolean found = false;
for (int i = 0; i < people.length; i++) {
if (! found) {
if (people[i].equals ("Don")){
sendAlert();
found = true;
}
if (people[i].equals ("John")){
sendAlert();
found = true;
}
}
}
}
這樣的控制旗標帶來的麻煩超過了帶來的便利 我們應該用 break 或是 continue
void checkSecurity(String[] people) {
for (int i = 0; i < people.length; i++) {
if (people[i].equals ("Don")){
sendAlert();
break;
}
if (people[i].equals ("John")){
sendAlert();
break;
}
}
}
Replace Nested Conditional with Guard Clauses
當你函式中的條件邏輯複雜 使人難以看出正常情況的執行路徑 就可以使用guard clause來表現所有特殊狀況
來看下面這個程式
public double getPayAmount() {
double result;
if (isDead){
result = deadAmount();
}
else {
if (isSeparated){
result = separatedAmount();
}
else {
if (isRetired){
result = retiredAmount();
}
else{
result = normalPayAmount();
}
}
}
return result;
}
很難看得出 正常情況應該是第二個條件的第二個條件的第二個條件 我們應該重構成這樣
public double getPayAmount() {
if (isDead){
return deadAmount();
}
if (isSeparated){
return separatedAmount();
}
if (isRetired){
return retiredAmount();
}
return normalPayAmount();
}
這樣一目了然
大方向就是 if-else的條件給人的感覺是 if的情況跟else的情況同等的重要
但guard clause不同 就是用來專門處理比較特別的情況
Replace Conditional with Polymorphism
當你發現switch裡面的判斷式彼此是subclass的關係 那就可以用多型
Introduce Null Object
如果其中一個條件選項是null 那你可以考慮用Null Object