2014-12-30 79 views
2

我目前正在開發一個項目,這個項目分爲幾個部分,核心,用戶界面等。直到很難改變項目架構,我想知道什麼是最好的工作方式核心庫中的異常?我的意思是,如何組織這些例外?例如,我可以用有意義的消息拋出系統異常:核心庫的異常體系結構

// Database implementation within Core library 
class Database 
{ 
    void Foo() 
    { 
     // ... 
     if (Something()) 
      throw new InvalidDataException(message:"The something!"); 
     else 
      throw new InvalidDataException(message:"It's not something!"); 
    } 
}  

class UI 
{ 
    void ShowDatabase() 
    { 
     var database = new Database(); 
     try 
     { 
      database.Foo(); 
     } 
     catch (InvalidDataException e) 
     { 
      CleanUp(); 
      MessageBox.Show(e.ToString()); 
     } 
    } 
} 

但是核心庫不必以任何方式處理用戶。我對嗎?好的,還有另外一種方法。我可以拋出系統異常,錯誤代碼爲異常消息使UI層可以選擇警告信息用戶本身:

static class ErrorCode 
{ 
    static string Something = "SomethingOccur"; 
    static string NotSomething = "NotSomethingOccur"; 
} 

class Database 
{ 
    void Foo() 
    { 
     // ... 
     if (Something()) 
      throw new InvalidDataException(message:ErrorCode.Something); 
     else 
      throw new InvalidDataException(message:ErrorCode.NotSomething); 
    } 
}  

class UI 
{ 
    void ShowDatabase() 
    { 
     var database = new Database(); 
     try 
     { 
      database.Foo(); 
     } 
     catch (InvalidDataException e) 
     { 
      if (e.Message == ErrorCode.Something) 
      { 
       CleanUpSomthing(); 
       MessageBox.Show(Resources.SomethingMessage); 
      } 
      else if (e.Message == ErrorCode.NotSomething) 
      { 
       CleanUpSomethingElse(); 
       MessageBox.Show(Resources.NotSomethingMessage); 
      } 
     } 
    } 
} 

現在,它更靈活,但e.Message == ErrorCode.Something長得難看,我想。還有第三種方式,分別實施任何情況下的例外:

class SomethingException : Exception 
{ 
    public SomethingException(string message = null, Exception inner = null) : base(message, inner) { } 
} 

class NotSomethingException : Exception 
{ 
    public NotSomethingException(string message = null, Exception inner = null) : base(message, inner) { } 
} 

class Database 
{ 
    void Foo() 
    { 
     // ... 
     if (Something()) 
      throw new SomethingException() 
     else 
      throw new NotSomethingException(); 
    } 
}  

class UI 
{ 
    void ShowDatabase() 
    { 
     var database = new Database(); 
     try 
     { 
      database.Foo(); 
     } 
     catch (SomethingException e) 
     { 
      CleanUpSomething(); 
      MessageBox.Show(Resources.SomethingMessage); 
     } 
     catch (NotSomethingException e) 
     { 
      CleanUpSomethingElse(); 
      MessageBox.Show(Resources.SomethingMessage); 
     } 
    } 
} 

它看起來更好,但會有數以百計的各種情況下在某一時刻的異常。聽起來很糟糕。

因此,問題是 - 處理Core庫中的異常的最佳方法是什麼?也許有什麼最佳做法?

P.S.對不起,我的英語,順便說一句。

+0

使用錯誤代碼。如果您真的想要檢測到特定的錯誤,BCL不會這麼做,這是一個主要的問題。 SqlException有錯誤代碼,它非常有用。 Exception.Message是供開發人員閱讀的,而不是用戶。 – usr

+0

通過實現[fail fast](http://en.wikipedia.org/wiki/Fail-fast)架構,您通常可以減少編寫如此多的異常處理代碼的需求 –

回答

6

一般的做法應該是這樣的:

  1. 您可以在異常類型的特定狀況相一致任何情況下使用標準的.NET異常類(如ArgumentNullExceptionInvalidOperationException)。有很多.NET異常類,你需要了解它們以知道哪一個拋出什麼,什麼時候拋出。

  2. 在錯誤與您的Core庫的邏輯嚴格相關的情況下,您可以定義自己的異常類,並使用它們進行拋出。

  3. 您應該創建一個異常層次結構,基本異常類代表一般錯誤,更具體的異常類從它們繼承。例如,您定義的基本異常類可能會被命名爲:ex。 CalculationExcepion。然後定義從它繼承的類 - 指定特定類型的計算異常。通過這種方法,您的庫的用戶將能夠捕獲一個基本異常(以涵蓋許多錯誤情況),或根據他們的偏好處理特定異常。

  4. 你可以在你的例外引入額外的性能,但要小心像ErrorCode性質不與可能有50個不同的錯誤代碼 - 這將是難以辦理的用戶一個通用的異常類落得你的Core庫。您可以在有限數量的特定錯誤類型的特殊情況下使用ErrorCode等屬性,例如在執行GET請求時獲得的HTTP代碼:200,500,404和其他一些代碼 - 但仍然是數量有限。

  5. 您的Core庫中的公共方法和屬性應該記錄它們拋出什麼類型的異常以及何時可以預期這些異常。

相關問題