2014-01-31 79 views
0

實際上/邏輯上不能達到的代碼,我有一個接口:避免在catch子句

public interface FileRepository { 
    String insert(File file) throws IOException; 
    // other methods ... 
} 

我的insert(File file)實現使用當地(避免併發問題)java.security.MessageDigester會拋出其工廠方法檢查異常java.security.NoSuchAlgorithmException

​​

我的做法:作爲NoSuchAlgorithmException永遠是一個致命的錯誤(這使得模塊完全不可用),我嘗試在我的構造函數測試的參數digestAlgo初始化MessageDigest,所以異常可以通過構造函數拋出,其他(早)比從insert(File)。另一個原因是界面不允許按定義投擲NoSuchAlgorithmException

我的問題:在我的實現,代碼

} catch (NoSuchAlgorithmException e) { 
     LOGGER.fatal(MD_INIT_ERROR, e); 
     return null; 
    } 

永遠不會達到,所以我覺得應該有更好的解決方案,它允許以避免(在邏輯上和實際上)可達代碼。

任何解決方案/建議將受到歡迎,謝謝。

編輯:

運行代碼時並不是真正的問題。但在測試中,由於代碼無法訪問,再加上一些「試圖捕獲資源」,質量分析工具(sonar,pmd)將考慮代碼「單元測試的分支覆蓋不足」,這是一個主要問題。分析報告,這就是爲什麼我想要避免這段代碼。

另一個問題,是在我的構造函數中測試MessageDigest.getInstance(digestAlgo);的好習慣嗎?或者讓insert(File)承擔NoSuchAlgorithmException的全部責任?

+0

...如果它被定義爲必須被捕獲,那一定是。如果它是致命的,則拋出一個運行時異常並將根源鎖定。我沒有看到問題。 –

+0

@DaveNewton感謝評論。運行代碼時不是真正的問題。但是在測試中,由於代碼無法訪問,再加上一些帶有資源的「try-catch」,質量分析工具(sonar,pmd)會考慮代碼「單元測試的分支覆蓋率不足」,這是一個主要問題在分析報告中,這就是爲什麼我想要避免這段代碼。 – ren78min

回答

1

這個班有太多的事情要做。如果是這樣,就像它的名字所暗示的那樣,一個文件存儲庫的重點應該放在存儲文件上,但是顯然有很多與獲取MessageDigest實例無關的活動 - 如果這個類負責創建一種隧道(通過靜態方法)依賴於MessageDigest?有許多依賴注入的選項,所有這些選項都可以讓您卸載責任,將對象配置爲專用於此目的的框架(Spring,Guice,PicoContainer等)。

我想你認識到了這裏的問題,所以這是一個很好的開始。作爲一個規則,你應該努力不要拋出異常,通常對象構造函數是我最不喜歡的地方。如果您使用框架來幫助您配置對象,那麼您在這裏面對的尷尬可能完全消失。此外,不是一次,而是兩次,你返回null - 它會讓你在方法調用的另一端檢查null,你真的想這麼做嗎?如果你有這個想法,我敢打賭你會想找到另一種方式(而且你有其他選擇)。另外,你會發現用一個專門的對象創建工廠(這些依賴注入框架就是這樣)來配置你的對象將會幫助你更鬆散地將你的組件組合在一起,這將促進測試組件的可能性與其真正的依賴關係隔離 - 使用mock進行測試。如果你可以在思考你在哪裏寫代碼的單元測試的時候進行轉變,那麼你應該期望看到更好的設計幾乎無意識地開始發生。GOOS這本書是一個很好的資源。最好的祝願!

編輯:我誤讀 - 看起來像你只返回null一次,但這仍然是一次太多。 : -/

+0

+1這麼多有用的想法。我不知道在我的設計中有什麼問題,但在得到答案之前並不確定。正如你所說,工廠可以解決問題。非常感謝你。 – ren78min

0

我想我會改變構造函數採取MessageDigest而不是算法名稱,並讓調用者處理異常。但這裏還有另一個問題。將消化器作爲實例成員意味着該類不是線程安全的。