java - 设计模式 - 验证输入参数并创建持有者类,J2SE(无框架等)

标签 java oop design-patterns object-oriented-analysis

场景:我们收到关于一个对象的几个输入参数,例如类(class)

类(class)有导师姓名、学生人数、类(class)时间、房间号等。

我们需要验证(学生人数 > 0、上午 9 点 < 时间 < 晚上 9 点等)输入并创建对象。我们需要返回无效输入的错误源。

我可以想到两种方法

1) 用静态方法创建一个单独的Validator类,

  • 验证输入,(验证方法返回 true,或一些枚举,如 VALID、INVALID_TIME、INVALID_STUDENT_NUMBER)。
  • 如果输入有效则实例化 Bean。

缺点:

  • 如果我们必须在验证输入值之前处理输入值,如果输入有效,上述模式会导致执行两次,一次在 Validator 类中,一次在 bean setter 之前。我们不能返回 Bean 对象,因为验证方法需要在无效的情况下返回错误源。

2) Bean类本身有validate方法,无效输入返回异常。通过不同类型的异常来追溯错误来源。

缺点:

  • 需要创建多个自定义异常(exception)。
  • 在 holder 对象本身中包含验证方法是否正确?

我探索了几种设计模式,但它们并不相关。

请帮助我了解上述方法的优缺点,以及更好的方法。

最佳答案

其中一位评论员指出:“您最终会希望得到一系列验证错误。”这很重要。

根据我的经验,他们的模型对象内部的验证方法不起作用,因为验证逻辑经常变化,并且因为在一组情况下无效的东西在另一组情况下有效。例如,如果验证方法认为晚于晚上 9 点的任何内容都是无效的,则学校管理人员可以更改规则,以便夏季学期的类(class)可以运行到晚上 11 点。当这种事情发生时,您不希望在类中使用验证方法,这是不可避免的。

此外,通常不可能在不知道系统中其他对象状态的情况下验证对象。例如,如果您有一个 Loan 对象,超过 100,000 美元的贷款值可能无效,当 Customer 对象的类型为 Institution 时除外。您需要了解 Loan 和 Customer 对象才能正确验证贷款。

我见过的复杂验证的最佳实践是:

  1. 在接受对象之前,简单的事情是有效的。这包括检查数字字段中的无效字符或非数字。

  2. 创建一个验证框架,一次验证一组依赖对象。不要在发现第一个错误时停止验证例程。相反,创建一个名为 ValidationError 的类,并让您的框架创建这些对象的集合。这种方法让您可以考虑对象内和对象间的依赖关系。此外,您可以一次将所有错误呈现给用户,而不是强制用户一次一个地更正错误。

  3. 不要对 minimumNumberOfStudents 或 latestClassTime 等值进行硬编码。相反,将这些值放在关系数据库表或配置文件中。让验证框架查找正确的值(然后缓存它们)。当值发生变化时(通常会发生变化),您只需要更新文件或数据库;无需重建和重新部署整个应用程序。当我做这项工作时,我正在用 Smalltalk 编码。如果您使用的是 Smalltalk 或 Ruby 等动态语言,则很容易将源代码作为“验证 block ”实际放入数据库并在运行时执行。

验证框架可能会使用异常,但我不建议这样做。应该为更难以恢复的更严重的错误保留异常。此外,异常会导致很大的性能损失,如果验证是在服务器而不是客户端上完成的,这一点很重要。更糟糕的是,一些平台的异常处理不稳定。

关于java - 设计模式 - 验证输入参数并创建持有者类,J2SE(无框架等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7988920/

相关文章:

java - 使用 Bouncy CaSTLe 和 PDFBox 在 Java 中验证 PDF 签名

java - 设计模式 - 从不同类型的数据源创建对象

java - 将装饰器设计模式用于类的层次结构

java - 具有操作传递的装饰器模式?

java - 通过LAN网络(java)发送和监听swing事件?

java - 对象的区域 - 抽象类 - Java

java - 初学者 JDBC 结果集问题

c# - 领域层类的范围

java - 观察者模式与单一职责原则的违背

java - 使用 java.util.Calendar 存储和检索对象中存储的日期