数据验证设计模式
如果我有一个数据库表的集合(例如,在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都提供了基本形式的约束,例如要求列中值的唯一性或者列表中的值等)。
(针对各个字段的)输入验证当然是另一回事,并且即使数据库具有对表列的明确定义的约束,任何应用程序仍应执行该操作(以在出现问题时向用户提供良好的反馈)。