在底層開發程式的時候我常看到一個關鍵字之 IsSuccess 、 Fail 、Error 在不同的 Service 中都有出現
我就在想是因為大家的寫作都是一樣的風格嗎,後來我才知道原來是一種 Result Pattern 的設計跟導入

Result Pattern 簡單的說有兩個很重要的狀態
成功 - Result.Success(value)
失敗 - Result.Fail("reason")
C# Code for Result Pattern :
public class Result
{
public bool IsSuccess { get; }
public string Error { get; }
public T Value { get; }
private Result(bool ok, T value, string error)
{
IsSuccess = ok;
Value = value;
Error = error;
}
public static Result Success(T value)
=> new Result(true, value, "");
public static Result Fail(string error)
=> new Result(false, default(T), error);
}
看起來很簡單,但是就可以讓很多錯誤訊息統一化
使用方式
C# Code:
public Result CreateUser(string name, string email)
{
if (string.IsNullOrWhiteSpace(name))
return Result.Fail("Name is required");
if (string.IsNullOrWhiteSpace(email))
return Result.Fail("Email is required");
var user = new User(name, email);
return Result.Success(user);
}
這些都是預期內錯誤 不需要 try/catch
呼叫端寫法更乾淨
var result = CreateUser("Donma", "");
if (!result.IsSuccess)
{
Console.WriteLine("Error: " + result.Error);
return;
}
Console.WriteLine("Created: " + result.Value.Name);
流程像在寫規格 不是一堆防呆與例外控制
遇到不可預期的錯誤怎麼辦
Result Pattern 不用來取代真正的 exception 它只處理 "預期內的錯誤"
不可預期的錯誤交給 exception
例如 DB 掛掉、Redis timeout、File I/O 堵塞、連外 API 掛掉、NullReferenceException、SDK 錯誤..等
這些才是 exception 的領域
正確方式是 Service 層用 try/catch 包住預期外錯誤 然後轉成 Result.Fail
public Result SaveToDb(User user)
{
try
{
_db.Save(user);
return Result.Success(user);
}
catch (Exception ex)
{
return Result.Fail("Database error: " + ex.Message);
}
}
商業邏輯的錯誤用 Result 回傳 系統層級的不可預期錯誤用 try/catch 包起來 真正無法處理的 bug 就讓它 throw 給系統監控 這樣整個錯誤處理的分工會非常清楚 程式的流程也能更可預期 結構保持一致 不需要再依賴
null 呼叫端的寫法自然 也不會到處充滿 try/catch 說穿了就是方便 debug 還有測試 難怪我在看很多 open soruce 都這樣設計