2017-03-20 20 views
-1

我陷入了設計問題。 我的問題是,我對問題的解決方案不乾淨。代碼看起來不太好。設計許多不同的更新對象?

這就是我想做的事:

我有性的判定存儲值的普通類。 類的值必須符合某些規則。

這是一個簡單的例子: 值類:

class RecivedOrder 
{ 
    public AgreementId { get; set; } 
    public OrderNr { get; set; } 
    public Items { get; set; } 
    public ProductId { get; set; } 
    public ValidProductId { get; set; }   
    public InStock { get; set; }   
    public CustomerId { get; set; }  
    public NameOfCustomer { get; set; }   
    //..and many more properties.. 
} 

驗證/更新完成一個階級是這樣的:

foreach (RecivedOrder o in RecivedDocument.Orders) 
{ 
    RecivedOrder.AgreementId = CheckIfValidAgreementId(o.AgreementId); 
    RecivedOrder.ValidProductId = (bool)CheckIfValidProductId(o.ProductId); 
    RecivedOrder.InStock = (bool)CheckProductIsInStock(o.ProductId); 
    RecivedOrder.NameOfCustomer = GetNameOfCustomer(o.CustomerId); 
    // ...and many more checks/validations.... 

    // The check methodes can do call to database.. 

} 

我所尋找的是一個好的設計模式爲了這。 或者更乾淨的方法來做到這一點?

問候 弗雷德裏克

回答

0

就個人而言,我喜歡用驗證的情況下一個模式是創建一個ValidationResults類,並有一個是我的驗證的返回值和更新功能,我的對象。像這樣的東西(超級簡單的例子):

public class ValidationResult 
{ 
    public bool IsValid { get; set; } 
    public string Message { get; set; } 
} 

然後,我可能會只定義在我ReceivedOrder類驗證方法返回這個類的一個實例:

public ValidationResult Validate() 
{ 
    var result = new ValidationResult(); 
    result.IsValid = true; 

    if (!CheckIfValidAgreementId(this.AgreementId)) 
    { 
    result.IsValid = false 
    result.Message = "Invalid agreement ID"; 
    } 
    else if (!CheckIfValidProductId(this.ProductId)) 
    { 
    result.IsValid = false; 
    result.IsValid = "Invalid product ID"; 
    } 

    // ... and so on, with other validations 

    return result; 
} 

然後我可能會創建對象,這使得確保驗證發生在一個更新的方法,並將結果返回了

public ValidationResult Update() 
{ 
    var validationResult = this.Validate(); 

    if (validationResult.IsValid) 
    { 
    // ... your code to actually update the repository goes here 
    } 

    return validationResult; 
} 

現在,在你的代碼的其餘部分,你可以調用更新的對個別對象,並檢查返回的結果.IsValid來驗證更新是否成功。如果你需要更新倍數,你可以通過它們循環。

foreach (ReceivedOrder o in RecivedDocument.Orders) 
{ 
    var result = o.Update(); 

    if (!result.IsValid) 
    MessageBox.Show("failed to update order: " + result.Message); // or however you need to handle this 
} 

或者,你可以調用Update之前自己打電話驗證,如果適合你的使用情況較好

foreach (ReceivedOrder o in RecivedDocument.Orders) 
{ 
    var result = o.Validate(); 

    if (!result.IsValid) 
    MessageBox.Show("validation failed: " + result.Message); 
    else 
    o.Update(); 
} 
+0

我覺得我用你的建議在這裏。謝謝! – Hasle

0

完全私人瓦爾實現你的屬性和獲取/ Set實現。然後你可以在set方法中進行檢查。例如:

private object _agreementId; 
public object AgreementId 
{ 
    get { return _agreementId; } 
    set 
    { 
     if(!CheckIfValidAgreementId(value)) 
      throw new ArgumentException(); 
     _agreementId = value; 
    } 
} 
0

您可以如下編寫你的應用程序:

foreach (RecivedOrder o in RecivedDocument.Orders) 
{ 
    if (!ReciveOrder.Check()) 
    { 
    ... // Display order content on console 
     // Then show errors: 
    for (int i=0;i<Errors.Count;i++) Console.Writeline(Errors[i]) ; 
    } 

class RecivedOrder 
{ 
    // your properties 
    internal List<String> Errors = null ; 

    internal bool Check() 
    { 
    Errors = new List<String>() ; 
    CheckAgreementId() ; 
    CheckProductId() ; 
    ... // other checks 
    return Errors.Count==0 ; 
    } 

    internal void CheckAgreementId() 
    { 
    bool IdOk = AgreementId>=0 ; 
    ... // more controls on AgreementId 
    if (!IdOk) Errors.Add("Invalid AgreementId="+AgreementId) ; 
    } 

    internal void CheckProductId() 
    { 
    ... 
0

我發現它在設計對象時,有助於定義課程的目的。例如,這是一個代表數據庫實體或對象的對象,以簡單地在點之間存儲數據(即DTO),或者屬性必須遵守某些規則(即模型)的對象或其他類似業務對象的其他對象也具有某些行爲。

看起來你可能屬於模型類別。除了這裏提供的答案,您也可以考慮解決方案,如

+0

FluentValidation librarie看起來不錯。謝謝! – Hasle