程式小技巧 — 提前返回 (Early return)

提前返回 (Early return),又稱防衛語句(Guard clause),是一種程式的設計模式: 在函式或方法的執行過程中,只要一滿足條件,不繼續執行,立刻退出。 在絕大多數的情況下 Early return 能夠提升程式碼可讀性、減少程式碼嵌套、避免程式碼過度複雜。

直接看範例比較快,在許多古老的系統或是新手的程式碼中都會看到這種波動拳程式碼:
    
public bool RegisterUser(string email, string username, string password, string confirmPassword)
{
    if (string.IsNullOrEmpty(email))
    {
        var regex = new Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
        if (regex.IsMatch(email))
        {
            if (string.IsNullOrEmpty(username))
            {
                if (string.IsNullOrWhiteSpace(password))
                {
                    if (password.Length < 4)
                    {
                        if (password == confirmPassword)
                        {
                            // TODO: 寫入資料庫
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}
    

在比對的時候需要上下跳來跳去,if 越多越痛苦,在上面的範例中還只是簡單的 return false ,有的還要處理其他的邏輯,非常複雜,出現問題時要確認邏輯真的是一種酷刑。

現在許多開發工具都有提供一個功能:invert 'if'
可以很輕易的把程式碼轉換成下面的樣子:
  
public bool RegisterUser(string email, string username, string password, string confirmPassword)
{
    if (!string.IsNullOrEmpty(email))
    {
        return false;
    }

    var regex = new Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
    if (!regex.IsMatch(email))
    {
        return false;
    }

    if (!string.IsNullOrEmpty(username))
    {
        return false;
    }

    if (!string.IsNullOrWhiteSpace(password))
    {
        return false;
    }

    if (password.Length >= 4)
    {
        return false;
    }

    if (password != confirmPassword)
    {
        return false;
    }

    // TODO: 寫入資料庫
    
    return true;
}


雖然程式碼邏輯沒有被刪減,但是可讀性提升了很多。

參考資料:
Wiki - Guard (computer science)

留言