函數中的條件邏輯使人難以看清正常的執行途徑。使用衛語句表現所有特殊情況。
動機:條件表達式通常有2種表現形式。第一:所有分支都屬於正常行爲。第二:條件表達式提供的答案中只有一種是正常行爲,其他都是不常見的情況。
這2類條件表達式有不同的用途。如果2條分支都是正常行爲,就應該使用形如if……else……的條件表達式;如果某個條件極其罕見,就應該單獨檢查該條件,並在該條件爲真時立刻從函數中返回。這樣的單獨檢查常常被稱爲“衛語句”。
Replace Nested Conditional with Guard Clauses (以衛語句取代嵌套條件表達式)的精髓是:給某個分支以特別的重視。它告訴閱讀者:這種情況很罕見,如果它真的發生了,請做一些必要的整理工作,然後退出。
衛語句
在代碼中存在過多條件語句的時候,建議把多層條件語句改爲衛語句或其他方式
推薦儘量少用else, if-else的方式可以改寫成:
if(condition){
...
return obj;
}
// 接着寫else的業務邏輯代碼;
衛語句就是把複雜的條件表達式拆分成多個條件表達式,比如一個很複雜的表達式,嵌套了好幾層的if - then-else語句,轉換爲多個if語句,實現它的邏輯,這多條的if語句就是衛語句.
if(obj != null){
doSomething();
}
轉換成衛語句以後的代碼如下:
if(obj == null){
return;
}
doSomething();
有時候條件式可能出現在嵌套n次才能真正執行,其他分支只是簡單報錯返回的情況,對於這種情況,應該單獨檢查報錯返回的分支,當條件爲真時立即返回,這樣的單獨檢查就是衛語句(guard clauses).衛語句可以把我們的視線從異常處理中解放出來,集中精力到正常處理的代碼中。
示例1
修改前
void func(void)
{
if(IsWorkDay())
{
printf("Error,is work day");
}
else
{
if(IsWorkTime())
{
printf("Error ,is work time");
}
else
{
rest();
}
}
修改後
void func()
{
if(IsWorkDay())
{
printf("Error,is work day");
return;
}
if(IsWorkTime())
{
printf("Error,is work time");
return ;
}
rest();
}
示例2
修改前
double GetPayAmount()
{
double result;
if (IsDead()) {
result = DeadAmount();
}
else {
if (IsSeparated()) {
result = SeparatedAmount();
} else {
if (IsRetired()) {
result = RetiredPayAmount();
} else {
result = NormalPayAmount();
}
}
}
return result;
}
修改後
double getPayAmount()
{
if (isDead()) {
return deadPayAmount();
}
if (isSeparated()) {
return separatedPayAmount();
}
if (isRetired()) {
return retiredPayAmount();
}
return normalPayAmount();
}
總結
函數中的if條件邏輯使人難以看清正常的分支執行路徑。使用衛語句表現所有特殊情況。
所謂衛語句,如果某個條件極其罕見,就應該單獨檢查該條件,並在該條件爲真時立刻從函數中返回。這樣的單獨檢查常常被稱爲“衛語句”。
————————————————