2012-12-19 125 views
3

你有一個不可變的對象,你可以在接受幾個參數的構造函數中設置它的內部變量。在不可變的構造函數方法中驗證構造函數參數是壞的還是好想法?

問題
你看到的任何問題,以驗證構造函數參數不可變對象的構造方法,如果沒有有效的扔ArgumentExceptions

(對我來說,這是有道理的,但我想如果要問有一些更好的方法或一些與此不正常 - 例如,如果它是一個更好的設計,從構造移動驗證到工廠)

或者,如果我被改寫的問題概括它:

是否確定把業務規則明智的邏輯構造方法?或者應該構造函數總是沒有什麼比設置對象的內部?

感謝

+3

關於術語的一點......缺省構造函數是由編譯器在沒有用戶提供的構造函數的情況下自動生成的,並且是無參數的。 – spender

+0

謝謝,我已經刪除了'default':) – pencilCake

回答

4

從某種意義上說,在構造函數本身中進行驗證是有意義的,因爲您知道它的所有用法都將通過該單一點,並且任何其他將使用您的代碼的開發人員都將因爲您的「低級」驗證。

如果您將驗證移動到調用鏈的更高位置,那麼您將類代碼保持清潔,但是您將代碼暴露給「您正在使用它錯誤」的錯誤的可能性。

+0

也許你可以通過在類本身上使用靜態工廠方法來獲得最好的兩種選擇,並且使構造函數是私有的? – Grundlefleck

+1

是的,這將是一個符合兩個願望的解決方案。 – dutzu

2

如果是我,我會把驗證參數之前,我將它們傳遞到構造函數。你永遠不知道你的代碼將如何發展,因此如果你在工廠進行驗證,你應該提供更多的可見性並且感覺「更清潔」。

4

構造函數驗證在無效數據的情況下有一個小問題:那麼你做什麼?你不得不拋出一個異常,如果你經常創建「無效」實例,這可能會很尷尬,並且性能會受到影響。

爲了在每次實例化對象時擺脫try ... catch,無論如何您都必須創建工廠。

我認爲工廠是一個很好的方法,但方式稍有不同 - 驗證賦給工廠方法的參數,然後創建一個(有效的)實例。

0

如果您可以選擇在哪裏提出例外,那麼只要在任何地方記住用try..catch來包圍它,就可以考慮到您的代碼庫的其他用戶。這往往不取決於課程的目的,以及你如何看待它的使用。但一致性也很重要。

有時,不要在其中引發異常,而是爲不可變類型提供單獨的ValidateInstance()函數。你的其他選擇就像你說的類創建(通過工廠或構造函數)或者類的用法(如果錯誤可以被更快拋出,通常是個壞主意,但有時候是有道理的)。

將它們放在構造函數中的優點是,如果您稍後再選擇它們,它們也將在Factory方法中顯示。

HTH

2

類應,以最好的它的能力,記錄它使擔保,並盡最大努力保持自身處於有效狀態,在任何時候。任何不合適的來電或將對象置於無效狀態都會產生異常。

這也適用於構造函數。不驗證其輸入的構造函數使其他人可能創建類的無效實例。但是,如果你總是驗證,那麼任何提及你班級的人都可以確信它是有效的。