2011-04-09 62 views
2

這裏就是我想要做的,我不知道要尋找什麼,或者什麼設計正確的方法是:設計模式爲動態繼承

我正在一個異常層次結構的應用。作爲其中的一部分,有一些例外有時會致命,其他時間是可以恢復的 - 無論是特定的實例是致命的還是可恢復的,都是在異常本身的運行時確定的。對於組織的目的,我希望能夠像做(我在python工作):

try: 
    mightThrowAnException() 
except RecoverableException: 
    handleThisException() 

然後我會碰到這樣的:

class MyException(...): 
    ... 

凡MyException既可以根據構造函數中發生的情況,將FatalException或RecoverableException作爲基類。

我知道我可以有兩個單獨的異常MyFatalExceptionMyRecoverableException再提高一個或有其他的代碼,但有將是一個很大的不同異常的不同類型的錯誤,它可以從多個地方被上調代碼和異常必須做一些事情,比如檢查錯誤日誌以確定這個實例是否應該是致命的,所以我認爲將所有這些代碼放入異常處理程序本身是有意義的。

那麼幾個問題:

  1. 鑑於我想要做什麼,這是一個很好的方式去了解它,或者是有這樣的事情更好的設計?
  2. 我讀過關於類工廠,但我沒有看到用這種方法動態更改基類的簡單方法,我考慮的其他事情是元類或重寫刪除方法__new__(),我不是真的確定這三種方法各有利弊。這些都是正確的方法還是我需要別的東西?
+0

嗯。您比我更瞭解您的特定需求,但是對於捕獲異常以確定其是否致命的代碼,在逐案的基礎上進行更合理嗎?除了日誌以外,你甚至可以處理一個致命的異常?雖然 – Cameron 2011-04-09 04:14:16

+0

我懷疑我已經處理了幾年前Jesse在Java項目中描述的類似問題,但總的問題仍然很有趣,它是我們應用程序的電子郵件網關。事實之後添加了很多錯誤處理和恢復。由於存在各種可能的(通常是泛型的)異常類型,我們最終將它們歸類爲RetryableException和FastFailException,並且只是將發生的任何錯誤都包裝進去,而不是將該異常聲明爲拋出異常。它成功了, Java的檢查異常使它有點複雜。 – 2011-04-09 04:49:56

回答

6

我的建議是將例外的內容與其含義分離。同樣的例外可以在不同的地方有不同的含義!

您的問題建議將異常轉換爲具有高級功能(如檢查日誌)的「感知」對象。但這不是例外的意圖。例外情況應該是輕量級數據對象,儘可能多地提供關於發生了什麼的信息,但不能自行確定應該對其做些什麼。捕捉代碼就是這樣做的,正如我上面所說的那樣,完全可以想象的是,某些異常將以某種方式在某個地方以另一種方式在其他地方處理。

+0

謝謝,我想我不確定在異常情況下應該處理什麼樣的事情。你能推薦任何閱讀嗎?目前,我只在異常中進行錯誤日誌記錄。但我想要這樣做的原因是因爲我有一些代碼與不可靠的服務器交談 - 應該允許偶爾失敗,但我希望異常檢查我的錯誤日誌,並且如果此錯誤似乎過於頻繁我需要它變得致命,因爲更大的可能是錯誤的。在例外情況下做這件事似乎是合乎邏輯的地方,你認爲這不是嗎? – 2011-04-09 04:42:36

+1

@Jesse,這個例外絕對不是處理這類事情的地方。應用程序應該是確定關於不可靠服務器的策略的地方。一個例外基本上是一個錯誤信息 - 它不應該包含做什麼的指示,否則,如果有已知的行爲方式,它不是一個例外。 – 2011-04-09 05:00:36

+0

明白了,謝謝!這讓我相信我需要重構我的代碼結構 – 2011-04-09 14:43:40

1

我可能只是用一個屬性去判斷一個異常是否是致命的,如果不能將一個特定的異常歸類爲致命的或可恢復的。

class MyBaseException(Exception): 
    def __init__(self, ..., fatal=True): 
     self.fatal = fatal 

class MyException(MyBaseException): 
    ... 

try: 
    do_something_that_raises() 
except MyBaseException, e: 
    if e.fatal: 
     logging.error(e) 
     raise 
    else: 
     recover_somehow(e) 

但是,異常的提出者應該不會告訴偵聽器異常是否是致命的。他們可能能夠處理被視爲致命的異常。例外的目的是聲明某些事情是錯誤的,然後讓潛在用戶確定他們是否可以從中恢復。