2011-12-17 79 views
2

我現在正在考慮一個應該在我的java程序中處理非法狀態的概念。 我已經介紹了一個在圖像上處理步驟的類。引入僅用於異常拋出的方法是一個糟糕的決定嗎?

public class ImageProcessor{ 
    public Image processImage(Image img){ 
     //do some processing steps 
    } 
} 

現在,我想介紹另一個類,它應該在處理之前檢查圖像。

public class ImageChecker{ 
    public void checkImage(Image img) throws ImageNotProcessableException{ 
     //for example, if the image has a width of 0 the full process 
     //should be broken, throw an exception 
     if (img.width=0) throw new ImageNotProcessableException("width is 0"); 

     //other conditions throwing also exceptions 

     // the image is fine, do nothing 
    } 
} 

這兩個類應該用在Coordinator類中。

public class Coordinator{ 
    public void coordinate(Image img) throws ImageNotProcessableException{ 
     //initialize both 

     imageChecker.checkImage(img); //if no exception is throw the process can run 
     imageprocessor.processImage(img); 
    } 
} 

現在的問題是,這種方式的異常(爲他們定義一個單獨的方法)是一種錯誤的編碼風格?這種設計的想法是爲了防止污染處理代碼和異常處理。我希望協調員拋出異常,我認爲這可能是一種有意義的方式。你覺得呢,這是一個好方法還是反模式? 謝謝!

+1

'imageChecker'確實是一個獨立的類,它對多個其他類是有用的,還是它執行的檢查實際上特定於'imageProcessor'? 'imageChecker'有多少種方法? –

回答

4

驗證方法本身是一個非常好的主意。你引入了很好的問題分離 - 在一個地方檢查先決條件和驗證,並在另一個地方實際處理。

但是使用不正確。 ImageProcessor應該熱切地撥打ImageChecker.checkImage()。否則,圖書館的客戶可能會忘記調用它並傳遞無效圖像。

另外* @ Damien_The_Unbeliever *提出了關於代碼結構的一個很好的觀點。

爲了使它花式儘可能我會創建一個ImageProcessor接口與兩個實現:一個執行實際處理和decorator實現(ImageChecker)執行驗證和驗證通行證對象到目標ImageProcessor

這樣你可以使用安全或快速(假設驗證是昂貴的)實現。同樣在未來,您可能會將其他元素引入chain,如緩存或分析。

+1

我正在寫幾乎完全相同的迴應! –

+0

這正是我的意圖。我想分開關注。如果我使用了Aspects,我會在一個方面做到這一點。你提到的在ImageProcessor中調用ImageChecker,我的意圖是完全去耦這兩個類並在協調器中加入它們的功能。我想提供協調員給其他客戶。 – martin

1

這並非不合理。雖然checkImage的存在只是爲了檢查是否可以處理圖像並且沒有其他返回類型,但它可以返回狀態代碼/對象而不是拋出異常並返回空值是合理的,例如,

ImageStatus status = checkImage(image); 
if (status.isOk()) { 
    processImage(image); 
} 

這將是類似於由零鴻溝檢查:

if (y != 0) { 
    z = x/y; 
} 

經過異常通常是爲在那裏你不能確認先驗的東西是否會成功或失敗,直到你試試吧,如情況較好,IOException。

1

我在這裏看到3個問題,並且將它們分開很有用。

  1. 調用者應該看到名爲「ImageProcessor」的類還是名爲「Coordinator」的類?

  2. 在主處理的獨立方法中驗證輸入是否好?

  3. 此代碼是否應該使用檢查的異常或未經檢查的異常?

我的答案是:

  1. 的類或你暴露接口,使用更漂亮的名字。所以,在這裏「ImageProcessor」比「協調器」好得多。 (「協調員」聽起來像是你不想公開的實現細節。)

  2. 這是一個實施決定。如果它使事情變得更加清晰,那麼將一些驗證邏輯分離成單獨的方法是很好的。但是,你需要小心陷入陷阱,認爲有可能預先處理在後期處理過程中可能出錯的所有事物。實際處理的方法仍然需要可以自由地拋出異常,以便儘可能準確地描述失敗,而不管最初的快速確認是什麼。此外,你想避免在兩個地方寫驗證碼,因爲這是不必要的代碼重複。所以,我對分離有點懷疑,但我需要看代碼。更有可能的是,最好將實際的圖像處理本身分成不同的子任務,並在您需要的地方進行驗證。

  3. 這是歷史悠久的Java檢查異常辯論,在我們的有生之年不會消失,這裏不可能總結。但是,我認爲共識相當強烈地轉向使用運行時異常而不是檢查異常。當然,傳統的API仍然使用檢查的異常。但是對於大多數新代碼,最好使用運行時異常而不是檢查異常,因爲這樣可以實現更健壯的代碼。 (檢查異常具有令人厭煩的特性,通常被包裝,重新包裝,吞噬或以其他方式被破壞,然後才能到達異常處理程序,並且通過使每個人的拋出子句變得更長,它們導致許多附帶損害。)

相關問題