2009-12-15 108 views
0

以下示例顯然是虛構的,但它恢復了在我正在使用的代碼基礎上完成驗證的方式。提高數據驗證的性能

類型A有兩個方法,具有以下特徵:

public void FirstMethod(TypeB param) 
public ValidationResult TryFirstMethod(TypeB param) 

當FirstMethod被調用,它需要對參數進行驗證。
因此,它調用TryFirstMethod來檢索表示驗證結果的對象。
如果ValidationResult的實例表示一切正常,則繼續執行,否則引發異常。

TryFirstMethod的實用工具是調用者,一個假設的TypeC,可以執行此方法並檢查實際方法是否會拋出。通過檢查ValidationResult上的屬性。
此外,ValidationResult的實例包含有關輸入錯誤的原因,如何解決該錯誤等信息。
這證明了這種類型的需要,而不是僅僅使用布爾值。

實際上,這種方法運行得很好,驗證數據並將本地化的錯誤消息返回給用戶非常容易。

唯一的問題是,由於某些檢查相當複雜,執行它們兩次變得有點貴。
它們最初由調用者完成,以確保實際的方法不會拋出。
然後再通過有問題的方法檢查輸入是否有效。

我找不到乾淨的方法來避免必須執行兩次檢查。
爲了使事情更加複雜,事實上解決方案應該使用標準方法,構造函數以及TypeB是「原始」類型,比如string或int。

回答

1

這聽起來像你的核心邏輯是這樣的:

  1. 驗證TypeB(調用TryFirstMethod)。
  2. 如果無效,則顯示錯誤消息。
  3. 如果有效(並且大概其他成員也是有效的),那麼對數據執行操作(作爲FirstMethod的一部分?)。
  4. 數據操作(FirstMethod)重新驗證輸入。

如果是這樣(有點)是正確的,你應該能夠改變設計成類似:

  1. 呼叫FirstMethod
  2. 驗證數據。
  3. 如果無效,則拋出驗證異常。
  4. 如果有效,請執行數據操作。

然後,您的用戶界面會調用FirstMethod,並期望操作成功,除非拋出異常,在這種情況下,您將顯示您的驗證消息。使用這種設計,您只需執行一次驗證。

+0

是的,你完全理解。事實上,異常本身就很昂貴,並且來自外部世界的數據可能經常失效。再次,性能問題。另外,我更願意儘可能避免異常。 – RobSullivan

+0

異常比較昂貴?如果驗證過程如您所述那樣複雜,那麼拋出異常的成本可能相比可以忽略不計。如果拋出一個異常的代價會產生有意義的影響,那麼就像在TryFirstMethod中那樣返回一個ValidationResult。 – akmad

0

由於第一種方法是void,爲什麼不直接調用它並返回ValidationResult呢?

您能否給我們提供任何背景知道爲什麼第一個和第二個代碼有相同的代碼 - 要運行兩次?

你可以簡單地擁有的第一個失敗,並通過錯誤消息回在該路線的用戶...

+0

無效只是爲了保持示例簡單。通常有一個返回類型。我不會僅僅因爲我對阿克馬德答案的評論中解釋的原因而使用例外。 – RobSullivan

0

在我眼裏最乾淨的解決方案是第三種方法:

public void FirstMethod(TypeB param, ValidationResult alreadyPerformedResult) 

因此用戶可以進行自己的檢查,並根據檢查結果調用所需的功能。所以你可以跳過檢查,只是測試測試結果是否也符合你的標準。

也許你可以添加一些東西到你的ValidationResult(例如函數名稱作爲字符串在最簡單的情況下),以便你確定給定的結果真的來自這個方法而不是另一個叫做TryMethod()。