场景:我们接收一对关于对象的输入参数,例如Course
课程有讲师姓名、学生人数、上课时间、教室号等。
我们需要验证(学生人数)> 0,9 am
我能想到两种方法
1)用静态方法创建一个单独的Validator类,- 验证输入,(验证方法返回true,或一些enum,如VALID, INVALID_TIME, INVALID_STUDENT_NUMBER)。
- 如果输入有效则实例化Bean。
缺点:
- 如果我们必须在验证输入值之前处理它们,那么上面的模式会导致在输入有效的情况下执行两次,一次在Validator类中,一次在bean设置器之前。我们不能返回Bean对象,因为validate方法需要在无效的情况下返回错误源。
2)在Bean类本身中拥有validate方法,对于无效输入返回异常。通过不同类型的异常跟踪错误的来源。
缺点:
- 需要创建多个自定义异常。
- 这是一个正确的方式,包括验证方法内部持有人对象本身??
我探索了几个设计模式,但它们并没有联系。
请帮助我了解以上方法的优缺点,以及更好的方法。
一位评论员指出:"您将希望以一系列验证错误结束。"这很重要。
根据我的经验,模型对象内部的验证方法不起作用,因为验证逻辑经常更改,而且在一组情况下无效的东西在另一组情况下有效。例如,如果验证方法认为晚于晚上9点是无效的,学校管理人员可以更改规则,以便夏季学期的课程可以运行到晚上11点。当这种事情发生时,您不希望在类中使用验证方法,因为它不可避免地会发生。
同样,在不知道系统中其他对象的状态的情况下验证对象通常是不可能的。例如,如果您有一个Loan对象,那么超过100,000美元的贷款值可能是无效的,除非Customer对象是Institution类型。您需要同时了解Loan和Customer对象,才能正确地验证Loan。
我所见过的复杂验证的最佳实践是:
-
接受对象前有效的简单事项。这包括检查数字字段中的无效字符或非数字。
-
创建一个验证框架,一次验证一组依赖对象。不要在发现第一个错误时就停止验证例程。相反,创建一个名为ValidationError的类,并让框架创建这些对象的集合。这种方法允许您考虑对象内部和对象间的依赖关系。此外,您可以一次向用户显示所有错误,而不是强迫用户一次一个地纠正错误。
-
不要硬编码像minimumNumberOfStudents或latestClassTime这样的值。相反,应该将这些值放在关系数据库表或配置文件中。让验证框架查找正确的值(然后缓存它们)。当值发生变化时(通常会发生),您只需要更新文件或数据库;不需要重新构建和重新部署整个应用程序。当我做这项工作时,我是用Smalltalk编写代码的。如果您使用的是Smalltalk或Ruby这样的动态语言,那么实际上很容易将源代码作为"验证块"放入数据库并在运行时执行。
就像上面提到的,有很多方法可以做到这一点。
如果我正在实现类似的东西,我会看一下这篇文章http://java.dzone.com/news/factories-builders-and-fluent-关于结合了构建器模式的流畅接口。
也许它适合你的需要。要特别注意bean部分的验证。
希望能有所帮助。