巢狀條件式通常為為複雜度高的區域。
以下紀錄簡化巢狀條件式的技巧
1.巢狀 if 轉換成 if then else + and。
先從最簡單的開始,e.g.
private String nestedCondition1() { String result = ""; if (isProcess) { if (isDone) { return result = result.concat("process is truedone is true"); } } return result; }
目標是第4和第5行巢狀if,我們使用 if + and,化解巢狀if。
private String fixByIfThenElse1() { String result = ""; if (isProcess && isDone) { return result = result.concat("process is truedone is true"); } return result; }
2.變化:原式 if 和 if 之間有statement。e.g.第5行新增 result = result.concat(“process is true”);
private String nestedCondition2() { String result = ""; if (isProcess) { result = result.concat("process is true"); if (isDone) { return result = result.concat("done is true"); } } return result; }
對於第5行有個轉換的小技巧。在2個 if 之間的 statement 可以轉換為 if(condition1 && ! condition2){statement};
需要注意的是 condition2 必須反轉。e.g.
if(condition1){ statement1; if(condition2){ statement2; } } ---------trans----------- if(condition1 && !condition2){ statement1; }else if(condition1 && condition2){ statement1; statement2; }
轉換 if-then-else + and
private String fixByIfThenElse2() { String result = ""; if(isProcess && !isDone){ result = result.concat("process is true"); }else if(isProcess && isDone){ result = result.concat("process is true"); result = result.concat("done is true"); } return result; }
3.變化: 原式最外層 if 產生相對應的 else。新增 9~11行
private String nestedCondition3() { String result = ""; if (isProcess) { result = result.concat("process is true"); if (isDone) { return result = result.concat("done is true"); } } else { result = result.concat("process is not true"); } return result; }
轉換 if-then-else + and,新增8~10行
private String fixByIfThenElse3() { String result = ""; if(isProcess && !isDone){ result = result.concat("process is true"); }else if(isProcess && isDone){ result = result.concat("process is true"); result = result.concat("done is true"); }else if(!isProcess){ result = result.concat("process is not true"); } return result; }
4.變化: 原式內層 if 產生相對應 else 。新增 8~10行
private String nestedCondition4() { String result = ""; if (isProcess) { result = result.concat("process is true"); if (isDone) { return result = result.concat("done is true"); } else { return result = result.concat("done is not true"); } } else { result = result.concat("process is not true"); } return result; }
轉換 if-then-else + and
private String fixAndNestedConditionSimple() { String result = ""; if (isProcess && isDone) { result = result.concat("process is true"); return result = result.concat("done is true"); } else if (isProcess && !isDone) { result = result.concat("process is true"); return result = result.concat("done is not true"); } else if (!isProcess) { result = result.concat("process is not true"); } return result; }
5.變化:外層 if 的 else 加入其他動作,12~17行
private String nestedCondition5() { String result = ""; if (isProcess) { result = result.concat("process is true"); if (isDone) { result = result.concat("done is true"); } else { result = result.concat("done is not true"); } } else { result = result.concat("process is not true"); if (isPrint) { result = result.concat("print is true"); } else { result = result.concat("print is not true"); } } return result; }
轉換對應的 if-then-else + and 為
private String fixByNestedCondition5() { String result = ""; if (isProcess && isDone) { return result = result.concat("process is truedone is true"); } else if (isProcess && !isDone) { return result = result.concat("process is truedone is not true"); } else if (!isProcess && isPrint) { result = result.concat("process is not true"); return result = result.concat("print is true"); } else if (!isProcess && !isPrint) { result = result.concat("process is not true"); return result = result.concat("print is not true"); } return result; }
總結:
照這種排列邏輯來看基本上所有的巢狀 if 都可以轉換 if then else + and的結構,差別只在於複雜度與可讀性的不同。
2.以衛述句取代巢狀條件式。
這個方法是從”重構:改善既有程式的設計”一書來的。
衛述句是指條件式中若有特別的判斷邏輯,必須明確的標示出來並立刻從函式中返回。e.g.
private String nestedCondition1() { String result = ""; if (isProcess) { if (isDone) { return result = result.concat("process is truedone is true"); } } return result; }
以衛述句改善為
private String fixByGuardClause1() { String result = ""; if (!isProcess) { return result; } if (isDone) { return result = result.concat("process is truedone is true"); } return result; }
2.變化:原式 if 和 if 之間有statement。e.g.第5行新增 result = result.concat(“process is true”);
private String fixByGuardClauseOrigin() { String result = ""; if (isProcess) { result = result.concat("process is true"); }else{ if (isDone) { result = result.concat("done is true"); }else{ result = result.concat("done is not true"); } } return result; }
以衛述句改善有2種形式,分別為是否在判斷邏輯加入 and 運算。
加入and運算後可以看到其第1種方式較為簡潔(不需要摻雜result = result.concat(“process is true”)),可讀性較高。
1.在判斷邏輯加入 and 。
private String fixByGuardClauseWithAnd2() { String result = ""; if(isProcess && !isDone){ return result = result.concat("process is true"); } if(isProcess && isDone){ result = result.concat("process is true"); return result= result.concat("done is true"); } return result; }
2.不加入 and。
private String fixByGuardClause2() { String result = ""; if(!isProcess){ return result; } result = result.concat("process is true"); if(isDone){ return result = result.concat("done is true"); } return result; }
3.變化型: 原式最外層 if 產生相對應的 else。新增 9~11行
private String nestedCondition3() { String result = ""; if (isProcess) { result = result.concat("process is true"); if (isDone) { return result = result.concat("done is true"); } } else { result = result.concat("process is not true"); } return result; }
以衛述句改善為
private String fixByGuardClause3WithAnd() { String result = ""; if(!isProcess){ return result.concat("process is not true"); } if(isProcess && !isDone){ return result.concat("process is true"); } if(isProcess && isDone){ result = result.concat("process is true"); return result.concat("done is true"); } return result; }
4.變化: 原式內層 if 產生相對應 else 。新增 8~10行
private String nestedCondition4() { String result = ""; if (isProcess) { result = result.concat("process is true"); if (isDone) { return result = result.concat("done is true"); } else { return result = result.concat("done is not true"); } } else { result = result.concat("process is not true"); } return result; }
以衛述句改善為
private String fixByGuardClause4WithAnd() { String result = ""; if(isProcess && !isDone){ result = result.concat("process is true"); return result = result.concat("done is not true"); } if(isProcess && isDone){ result = result.concat("process is true"); return result = result.concat("done is true"); } if(!isProcess){ return result = result.concat("process is not true"); } return result; }
5.變化:外層 if 的 else 加入其他動作,新增12~17行
private String nestedCondition5() { String result = ""; if (isProcess) { result = result.concat("process is true"); if (isDone) { result = result.concat("done is true"); } else { result = result.concat("done is not true"); } } else { result = result.concat("process is not true"); if (isPrint) { result = result.concat("print is true"); } else { result = result.concat("print is not true"); } } return result; }
以衛述句改善為
private String fixByGuardClause5WithAnd() { String result = ""; if (!isProcess && !isPrint) { result = result.concat("process is not true"); result = result.concat("print is not true"); return result; } if (!isProcess && isPrint) { result = result.concat("process is not true"); result = result.concat("print is true"); return result; } if (isProcess && isDone) { result = result.concat("process is true"); result = result.concat("done is true"); return result; } if (isProcess && !isDone) { result = result.concat("process is true"); result = result.concat("done is not true"); return result; } return result; }
無論使用衛述句或是if-then-else都可將難以理解的巢狀結構分解成簡單的表達式。