数据验证设计模式

时间:2020-03-05 18:48:17  来源:igfitidea点击:

如果我有一个数据库表的集合(例如,在Access文件中),并且需要对照一个规则集验证此集合中的每个表,该规则集既具有所有表的通用规则,又具有特定于其中一个或者子集的单个规则桌子,有人可以推荐一个好的设计模式进行研究吗?

具体来说,我想避免类似于以下代码:

void Main()
{
    ValidateTable1();
    ValidateTable2();
    ValidateTable3();
}

private void ValidateTable1()
{
    //Table1 validation code goes here
}

private void ValidateTable2()
{
    //Table2 validation code goes here
}

private void ValidateTable3()
{
    //Table3 validation code goes here
}

另外,我决定使用log4net记录所有错误和警告,以便可以将每个方法声明为" void",而无需返回任何内容。这是一个好主意还是最好创建某种可以捕获所有异常的" ValidationException"并将其存储在" List <ValidationException>"中,然后再将其全部打印出来?

我确实找到了它,看起来似乎可行,但是我希望实际上找到一些可以解决的代码示例。有什么建议?过去有没有人做过类似的事情?

在某些情况下,该程序将用Cor VB.NET编写,并且这些表很有可能存储在Access或者SQL Server CE中。

解决方案

回答

我将为每一个返回某种类型的ValidationSummary ...或者一个IList,具体取决于我们希望如何构造它。

我们还可以选择执行以下操作:

using(var validation = new ValidationScope())
{
   ValidateTable1();
   ValidateTable2();
   ValidateTable3();

   if(validation.Haserrors)
   {
       MessageBox.Show(validation.ValidationSummary);
       return;
   }

   DoSomethingElse();
}

那么ValidateTable只会进入当前范围,如下所示:

ValidationScope.Current.AddError("col1", "Col1 should not be NULL");

这样的事情。

回答

只是对此的更新:我决定采用Decorator模式。也就是说,我有一个实现" IValidateableTable"接口(包含" validate()"方法)的"通用"表类。然后,我创建了几个验证装饰器(也可以实现IValidateableTable`),可以将它们包装在要验证的每个表周围。

因此,代码最终看起来像这样:

IValidateableTable table1 = new GenericTable(myDataSet);
table1 = new NonNullNonEmptyColumnValidator(table1, "ColumnA");
table1 = new ColumnValueValidator(table1, "ColumnB", "ExpectedValue");

然后,我要做的就是调用" table1.Validate()",它通过装饰器展开,调用所有需要的验证。到目前为止,尽管我仍然愿意接受建议,但它似乎工作得很好。

回答

两种方法:

  • CSLA,其中使用业务对象上的匿名方法进行验证。
  • 阅读JP Boodhoo的博客,他在博客中实现了规则引擎,并发布了非常详细的文章和示例代码。我们还可以看到他在DNR电视剧中的工作,非常值得一看。

回答

我认为我们真的在谈论数据库世界中称为约束的概念。约束是数据库如何保证其包含的数据的完整性。将这种逻辑放在数据库中而不是在应用程序中更有意义(甚至Access都提供了基本形式的约束,例如要求列中值的唯一性或者列表中的值等)。
(针对各个字段的)输入验证当然是另一回事,并且即使数据库具有对表列的明确定义的约束,任何应用程序仍应执行该操作(以在出现问题时向用户提供良好的反馈)。