2011-12-14 20 views
0

我有代碼驗證:如何簡化我的驗證檢查代碼?

public IDictionary<string, string> ValidateForDeletion(Account ac) 
     { 
      var account = _accountRepository.GetPkRk(ac.PartitionKey, ac.RowKey); 
      if (account == null) 
      { 
       _errors.Add("", "Account does not exist"); 
       return _errors; 
      } 
      if (_productRepository.GetPk("0000" + ac.RowKey).Count() != 0) 
      { 
       _errors.Add("", "Account contains products"); 
       return _errors; 
      } 
      return _errors; 
     } 

我看到有很多很多的「迴歸_errors」線。有什麼方法可以整理代碼並保持功能?我看到了一個使用yield的例子,但不確定我是否可以使用這個方法。

+0

是否使用MVC? – Marc 2011-12-14 09:57:44

+0

對於所有驗證檢查,Extract方法如何? – 2011-12-14 09:58:22

回答

1
public IDictionary<string, string> ValidateForDeletion(Account ac) 
{ 
    var account = _accountRepository.GetPkRk(ac.PartitionKey, ac.RowKey); 
    if (account == null) 
    { 
     _errors.Add("", "Account does not exist"); 
    } 
    else if (_productRepository.GetPk("0000" + ac.RowKey).Count() != 0) 
    { 
     _errors.Add("", "Account contains products"); 
    } 
    return _errors; 
} 

這將擺脫你的多重return語句的

0

那麼你可以隨時拉額外的克魯夫特到它自己的方法:

public IDictionary<string, string> ValidateForDeletion(Account ac) 
{ 
    var account = _accountRepository.GetPkRk(ac.PartitionKey, ac.RowKey); 
    return BuildErrorsList(account); 
} 

private IDictionary<string, string> BuildErrorsList(Account account) 
{ 
    if (account == null) 
    _errors.Add("", "Account does not exist"); 
    if (_productRepository.GetPk("0000" + ac.RowKey).Count() != 0) 
     _errors.Add("", "Account contains products"); 
    return _errors; 
} 

由於良好的指導方針是,每種方法應該從事的一個抽象層次,否則你可能想把「低層次」的東西變成自己的方法。

0
public IEnumerable<ValidationResult> ValidateForDeletion(Account ac) 
{ 
    var account = _accountRepository.GetPkRk(ac.PartitionKey, ac.RowKey); 
    if (account == null) 
    { 
     yield return new ValidationResult("Account does not exist"); 
    } 
    if (_productRepository.GetPk("0000" + ac.RowKey).Count() != 0) 
    { 
     yield return new ValidationResult("Account contains products"); 
    } 
} 
0
  1. 它的效果並不理想,你的方法是改變狀態(_errors場),同時還返回現場 - 這使得它有點混亂。通常情況下,您可能會有一種方法來改變狀態(更改_errors有一個返回結果的函數。

  2. ValidateForDeletion方法在第一次失敗後返回,而不是將所有錯誤添加到字典中。你確定這是正確的行爲嗎?

如果重構了這一點,我可能會擺脫ValidateForDeletion的副作用(修改字段),並使其返回IEnumerable<string>。我也會讓它執行完整的驗證。顯然這將對調用代碼產生影響,因此您必須確保不會破壞任何內容。

public IEnumerable<string> ValidateForDeletion(Account ac) 
{ 
    var account = _accountRepository.GetPkRk(ac.PartitionKey, ac.RowKey); 
    if (account == null) 
    { 
     yield return "Account does not exist"; 
    } 

    if (_productRepository.GetPk("0000" + ac.RowKey).Count() != 0) 
    { 
     yield return "Account contains products"; 
    } 

    return; 
} 
0

你可以做一些類似的產量。如果您考慮按引用傳遞,您可以在對象或存儲庫中包含驗證代碼。

例如,我驗證,看看帳戶可以刪除,我可以使用IValidateDelete接口上的帳戶具有此方法:

bool account.IsValidForDeletion(ref ValidationErrors validationErrors); 

然後我就可以調用它並傳遞我的空驗證錯誤方法。如果結果是真的,那麼你很好。如果它是假的,它會將驗證錯誤附加到ValidationErrors對象的內部列表中。

public bool IsValidForDeletion(ref Validationerrors validationErrors) 
{ 
// 
if (something is valid) 
{ 
    return true; 
} 

validationErrors.AddError("Something is wrong, this cannot be deleted"); 

return false; 
} 

現在,你可以通過你所有的方法,像這樣運行:

public ValidationErrors ValidateABunchOfStuff() 
{ 
    ValidationErrors errors = new ValidationErrors(); 

    account.IsValidForDeletion(errors); 
    product.IsValidForDeletion(errors); 
    cake.IsValidForDeletion(errors); 

    return errors; 
}