(圖片來自: http://sourcemaking.com/)
以下為學習 Simplifying Conditional Expressions 的筆記.
Consolidate Conditional Expression
看原文例子比較容易懂! 一系列條件測試且都回傳相同的值,可將其集中成同一個條件式,然後抽取成一個方法.
優點: 簡化程式碼.
Consolidate Duplicate Conditional Fragments
看原文例子比較容易懂! 每個條件測試之後,若有相同的程式碼片段(代表每個條件都會執行該段程式碼),將其搬出讓所有條件共用程式碼片段.
優點: 簡化程式碼.
Decompose Conditional
看原文例子比較容易懂! 當程式碼中有複雜的條件陳述區段時,將 條件判斷 和 條件判斷內的程式碼 各自抽取成新的方法.
優點: 簡化原本複雜的條件陳述區段.
Introduce Assertion
利用 Assert 來驗證程式內的假設是否正確.
優點: 驗證意想不到的錯誤.
Introduce Null Object
系統中常常出現 "判斷某個物件是否為 null 的判斷式",產生一個空物件來取代 null.
Class NullCompany extends Company
{
/* 取得員工數目. */
public int getStaffNumber()
{
return 0;
}
/* 取得公司住址. */
public String getAddress()
{
return "";
}
}
/* 若沒有空物件的寫法. */
int staffNumber;
if (rebarCompany = null)
{
staffNumber = 0;
}
else
{
staffNumber = rebarCompany.getStaffNumber();
}
...
String address;
if (rebarCompany = null)
{
address = "";
}
else
{
address = rebarCompany.getAddress();
}
/* 使用空物件的寫法.
* 若該公司被掏空,就會傳進一個 NullCompany .
* 這樣空物件跟一般物件都共用同一段程式碼. */
int staffNumber =
rebarCompany.getStaffNumber(); // NullCompany 回傳0.
...
String address =
rebarCompany.getAddress(); // NullCompany 回傳空字串.
優點: 處理為 null 時的預設行為,全部集中至空物件中. 簡化原本需要判斷並處理 Null 的區段.
Remove Control Flag
看例子比較容易懂! 當程式中有一個用來當做條件控制旗標的變數,用 break 或 return 來取代.
以下為原文範例: 囧rz
/* 是否跟崩潰有關,一找到就停止比對. */
bollean isFound = false; // Control Flag.
for (int i = 0; i < list.length; i++)
{
if (isFound == false)
{
if (list[i].equals("魚翔拳"))
{
isFound = true;
}
else if (list[i].equal("蔡老頭"))
{
isFound = true;
}
else if (list[i].equal("五分埔"))
{
isFound = true;
}
}
}
/* 是否跟崩潰有關,一找到就停止比對. */
for (int i = 0; i < list.length; i++)
{
if (list[i].equals("魚翔拳"))
{
break;
}
else if (list[i].equal("蔡老頭"))
{
break;
}
else if (list[i].equal("五分埔"))
{
break;
}
}
優點: 簡化邏輯.
Replace Conditional with Polymorphism
條件判斷後的行為是根據物件的類型決定時,將其不同的行為抽出到各自的子類別(使用多型)當中.
/* 原本程式. */
String name = people.getName();
if (name.equal("AskaYang"))
{
System.out.prinln("我只是喜歡唱歌!!(哭哭)");
}
else if (name.equal("YuXiangChuan"))
{
System.out.println("嗚~(崩潰中)");
}
else if (name.equal("YangShinHsuan"))
{
System.out.println("我有憂鬱症!(藥袋上看診時間:案發後一天)");
}
Class AskaYang extends People
{
public String doSomethingWrong()
{
return "我只是喜歡唱歌!!(哭哭)";
}
}
Class YuXianChuan extends People
{
public String doSomethingWrong()
{
return "嗚~(崩潰中)";
}
}
Class YangShinHsuan extends People
{
public String doSomethingWrong()
{
return "我有憂鬱症!(藥袋上看診時間:案發後一天)";
}
}
...
/* 修改後的程式.
* 根據傳入的 People 子類別的不同,印出不同的訊息. */
System.out.println(people.doSomethingWrong());
優點: 當程式中反覆使用相同的條件判斷時,利用多型將不同行為封裝至子類別,原本程式碼中的條件判斷 可改成 傳入不同子類別 來取代.
Replace Nested Conditional with Guard Clauses
當巢狀判斷迴圈無法清楚表示出執行路徑時,使用 Guard Cluse 取代所有其他情形.
- 當使用 if - else 架構時,代表 if 跟 else 內的程式片段一樣重要.
- 當使用 Guard Cluse 時,代表 "這是很少發生的事件,若發生請做處理然後跳出!"
- 一個方法只有一個入口,但不一定只有一個出口(一個 Return).
/* 又帥又有錢才能做我的男朋友. */
public boolean beMyBoyFriend(People boy)
{
boolean result = false;
if (boy.isPoor())
{
result = false;
}
else
{
if (boy.isUgly())
{
result = false;
}
else
{
result = true;
}
}
return result;
}
/* 使用 Guard Cluse. */
public boolean beMyBoyFreind(People boy)
{
if (boy.isPoor()) // Guard Cluse.
{
return false;
}
if (boy.isUgly) // Guard Cluse
{
return false;
}
return true;
}
優點: 增加閱讀性.
0 則回應: