2013-08-23 23 views
1

在正常情況下,如果函數失敗,例如未在數據庫中找到記錄或者表示可能缺少值的任何其他情況,建議使用異常來處理這種情況?正在使用正常控制流程的例外嗎?

實施例的僞代碼:

function retrieve(foo): 
    results = db.query("SELECT * FROM bar WHERE foo="+foo) 
    if not results: 
    throw Exception("no results") 
    return results[0] 

function main: 
    try: 
    record = retrieve(42) 
    except: 
    print "no record with 42" 
    .... will create the record and continue 
    else: 
    print "record found: "+record 
    .... will use the existing record and continue 

另一種解決方案可能會返回一個空值,而不是啓動此異常。 哪一個最有可能是反模式?在哪些情況下最好使用例外,哪些不適用?

回答

2

約書亞布洛赫總結了「有效的Java」:

異常,顧名思義,僅在用於特殊條件下使用;他們不應該用於普通控制流程

您可以在Google圖書上找到該書的相應片段(「項目57:僅針對特殊情況使用例外」)。

另外的原因是異常濫用會導致代碼很難理解布洛赫有一定的原因,其有效期爲今天的JVM實現:

因爲異常是專爲特殊情況下,很少有 激勵對於JVM實現者來說,使它們像顯式測試一樣快。

在(Hotspot)JVM的情況下,創建一個異常(想到生成的堆棧跟蹤)是相當昂貴的。

0

使用異常通常會導致更高的開銷並濫用它們可能會降低您的應用程序。沒有什麼例外關於找到查詢沒有記錄,所以我肯定會建議返回空。

因此,使用正常控制流程的異常並不是一個好的做法。

1

從.NET Framework Development Guidelines

,儘量不要使用異常控制的正常流動。

除了系統故障和具有潛在競爭條件的操作之外,框架設計人員應該設計API,以便用戶可以編寫不會拋出異常的代碼。例如,您可以提供一種方法在調用成員之前檢查先決條件,以便用戶可以編寫不會拋出異常的代碼。

用於檢查其他成員的先決條件的成員通常稱爲測試者,實際完成該工作的成員稱爲實施者。

有些情況下,Tester-Doer模式可能會導致不可接受的性能開銷。在這種情況下,應該考慮所謂的嘗試解析模式(有關更多信息,請參閱例外和性能)。