C# 为一个对象设计许多不同的更新?
我陷入了一个设计问题。 我的问题是我对这个问题的解决方案不干净。代码看起来不太好 这就是我想做的: 我有一个普通类,它的属性存储值。 类值必须根据某些规则进行验证 这是一个简化的示例: 价值类别:C# 为一个对象设计许多不同的更新?,c#,.net,oop,design-patterns,C#,.net,Oop,Design Patterns,我陷入了一个设计问题。 我的问题是我对这个问题的解决方案不干净。代码看起来不太好 这就是我想做的: 我有一个普通类,它的属性存储值。 类值必须根据某些规则进行验证 这是一个简化的示例: 价值类别: class RecivedOrder { public AgreementId { get; set; } public OrderNr { get; set; } public Items { get; set; } public ProductId {
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..
}
我要找的是一个很好的设计模式。
还是一种更干净的方法
致意
Fredrik使用私有变量和get/set实现完全实现您的属性。然后您可以在set方法内部执行检查。例如:
private object _agreementId;
public object AgreementId
{
get { return _agreementId; }
set
{
if( !CheckIfValidAgreementId(value))
throw new ArgumentException();
_agreementId = value;
}
}
就个人而言,我喜欢在验证情况下使用的一种模式是创建ValidationResults类,并将其作为对象上的Validate和Update函数的返回值。类似这样的内容(超级简单的示例): 然后,我可能会在我的ReceivedOrder类上定义一个Validate方法来返回该类的实例:
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;
}
然后,我可能会在对象上创建一个Update方法,以确保进行验证,并将结果返回
public ValidationResult Update()
{
var validationResult = this.Validate();
if (validationResult.IsValid)
{
// ... your code to actually update the repository goes here
}
return validationResult;
}
现在,在代码的其余部分中,您可以对单个对象调用Update,并检查返回的result.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之前调用Validate yourself,如果这更适合您的用例的话
foreach (ReceivedOrder o in RecivedDocument.Orders)
{
var result = o.Validate();
if (!result.IsValid)
MessageBox.Show("validation failed: " + result.Message);
else
o.Update();
}
您可以按以下方式对应用程序进行编码:
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()
{
...
foreach(RecivedDocument.Orders中的RecivedOrder o)
{
如果(!ReciveOrder.Check())
{
…//在控制台上显示订单内容
//然后显示错误:
对于(int i=0;i=0;
…//有关AgreementId的更多控件
如果(!IdOk)错误。添加(“无效的AgreementId=“+AgreementId”);
}
内部无效检查产品ID()
{
...
我发现在设计对象时定义类的用途很有帮助。例如,这是一个表示数据库实体的对象,还是一个只在点之间存储数据的对象(即DTO),还是一个属性必须遵守某些规则(即模型)的对象或者其他类似于业务对象的东西,也有一些行为
你可能会进入模型范畴。除了这里提供的答案,你也可以考虑诸如
之类的解决方案。- 自定义库,如
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()
{
...