2009-01-13 70 views
8

我在某處(現在無法找到它)讀取大的異常層次結構是浪費時間。這個陳述的理由在當時聽起來很合理,而且這個想法還伴隨着我。異常層次與錯誤枚舉

在我自己的代碼中,當我有一個代碼庫可以有一系列的錯誤條件時,我使用一個枚舉成員的異常來區分它們。

如果出現這種情況,我需要趕上這些錯誤之一,我抓住它,檢查枚舉並重新拋出,如果它不是我所期望的。理想情況下,這應該是罕見的。

我正在處理異常,我有一個反思時刻,在那裏我質疑了我的異常習慣。我很好奇別人做了什麼,爲什麼?

層次結構或數據成員有一個例外。

順便說一句,我假設你同意異常與錯誤代碼的想法。我不希望打開那些蠕蟲。

回答

12

規則很簡單:

  • 如果你最終檢查後,他們重新拋出異常,那麼你需要一個更細粒度的異常層次結構(除了其中檢查需要相當大的邏輯極少數情況下)。
  • 如果你有從不被捕獲的Exception類(只有它們的超類型),那麼你需要一個不太好的異常層次結構。
0

我喜歡針對不同類別的錯誤(例如致命/非致命條件或應用程序的特定圖層或模塊)使用少量例外。然後,異常的拋出者應該提供代碼以包含作爲異常的有效載荷。應用程序的表示層可以查找與代碼相對應的本地化人類可讀的錯誤消息。

總之,異常類型對開發人員非常有用,對應於錯誤代碼的消息對用戶很有用。

+2

@Andrew:關於「致命/非致命」的例外分類。這種分類應該在發現異常時確定,而不是拋出!因此它不能與異常類型相關。 – 2009-01-13 08:31:48

11

我認爲僅具有一個與嵌入式枚舉異常類型是次優的:

  1. 你不得不更頻繁地捕捉到了異常比必要的(並重新拋出它,一旦你已經確定你不能處理它)
  2. 枚舉本身成爲一個變化的熱點(所有的程序員需要修改它定期)
  3. 枚舉不分層,因此,例如,你不能用一個處理器輕鬆
  4. 處理所有IO錯誤有時你也想提供ca除了錯誤消息文本(例如,尚未找到的文件的路徑或從SQL服務器收到的錯誤號。將來自所有可能的錯誤場景的這些附加信息放入相同的異常使得處理更加麻煩。

要回答你的問題,我使用了異常的層次結構。它比它深廣得多。

3

根據我的經驗,太多的異常類只會變得令人困惑,特別是它們只能用於一個非常特定類型的問題。我看到一個系統,每個錯誤條件都有自己的異常,但只有超級類在catch塊中被檢查。這些子類完全浪費時間。

另一方面,不得不檢查枚舉並重新拋出異常使得代碼不那麼直觀,因爲你不能識別catch之後直接拋出的異常。也許只是一個小缺點,但如果經常使用它可能會影響可讀性。在需要非常快速的代碼中使用時,它也可能會帶來性能問題。

我不會使用枚舉解決方案,但有一些異常類型具有足夠廣譜的用途。像DatabaseException一樣,而不是像TableNotFoundException,ColumnNotFoundexception等幾個異常。根據我的經驗,這對大多數開發人員來說效果最好。您可以隨時添加一個帶有一些顯示給用戶的錯誤代碼的字段,以便於用戶與支持之間的溝通。

2

你不要有一個例外類型和枚舉亞型代替他們解決太多的異常類的問題。事實上,你只會變得更糟!

例如:假設您有異常類型Ex1..Ex99,例如, E14..E18是E1等的孩子,您現在決定用一個例外Ex和子類型ST1..ST99替換它們。你解決了什麼?沒有什麼 - 人們仍然需要處理所有可能性。你做得更糟?您不能忽視ST14-ST18並將它們視爲ST1的發生。你現在必須處理所有99種可能性,因爲你枚舉子類型沒有自然的,靈活的層次結構。

4

我認爲你是兩個世界中最糟糕的。大的異常層次結構是無用的,因爲客戶端已知是懶惰的,並且最終只會檢查頂層節點(可能只針對層次結構根節點)。你的枚舉系統不能解決這個問題,並且會導致一個更麻煩的異常捕獲系統。

如果你真的知道需要很多不同的異常和捕手會真正想要的不同的異常(知道,不是隱約覺得),與大層次繼續前進,忘記了枚舉。否則,堅持小的異常層次結構,只提供捕捉器真正感興趣的異常類。

1

不要將錯誤與異常混淆。
發生錯誤,儘可能地解決問題。
例外情況非常罕見,如果沒有更多上下文信息通常不可解決。

如果出現問題,可以修正本地,那麼你可能要使用錯誤代碼和處理它那裏,然後。

異常應該被用來調用堆棧傳播問題最多的是有足夠的信息來解決問題的上下文。

話說:枚舉沒有去,因爲他們繞過整個try抓機制,編譯器會自動爲你生成的方式。拇指

7

你不應該教條這一點。使用任何最適合解決問題的手段。我對這個經驗法則如下:

  • 只創建新的異常類,當你需要,需要不同的行爲異常。
  • 相反,當您只是想要包含例外情況下的額外信息時,將內容(枚舉,錯誤代碼,無論)添加到例外類中。除非您確實需要它們,否則不要創建新類。並記住,YAGNI ...