何时进行输入验证的最佳做法是什么?

时间:2016-04-21 13:58:15

标签: java

我正在开发一个涉及两个类的Java项目。一个是项目的驱动程序,另一个是程序的实际功能。驱动程序将从用户收集输入,值将用于创建另一个类的实例。另一个类对数据有什么限制(即一个值需要低于一定数量),我想知道何时应该验证输入是否符合这些要求。一般来说,输入验证是每个被实例化的类所担心的,或者是收集数据的类应该做的事情。

提前致谢。

1 个答案:

答案 0 :(得分:2)

与任何事情一样,"它取决于"。

让我们不要考虑整个应用程序,而是考虑各个组件。现在我们称他们为ApplicationHostBusinessLogic

BusinessLogic组件本身应该是完全可用的,并且可以被任何应用程序使用。因此,如果对其输入有假设或要求,则需要强制执行。例如,如果您要设置int值并且该值必须为正数,那么设置者应该强制执行该操作。像这样简单:

public void setSomeValue(int someValue) {
    if (someValue <= 0) {
        throw new NumberFormatException("Some Value must be a positive value.");
    }
    this.someValue = someValue;
}

这个想法是强制执行此约束是BusinessLogic责任。在违反此约束的情况下尝试使用BusinessLogic的任何消费代码都会出错。 BusinessLogic本身只是宣传其约束条件,并要求遵循它们。它并不关心用户体验,只关心系统状态。如果状态无效,请快速大声地失败。

那么ApplicationHost 也应该有相同的约束吗?您可能会问的问题是,if完全相同的ApplicationHost声明 重复

取决于。

请记住&#34;代码重复&#34;不是衡量相同击键的标准。它衡量的是相同的意图和责任。 ApplicationHost没有责任维护业务逻辑。但可能有责任提供良好的用户体验。这样做有几个选择:

  1. 直接将输入发送到业务逻辑,捕获并处理任何异常,向用户显示友好错误。
  2. 在调用业务逻辑之前自行验证输入,直接与用户交互以首先驱动该输入,并且只有当它有效时才实际执行业务操作。
  3. 第一个选项意味着更少的代码,应用程序层主要是业务层的传递。但是,这也意味着在可能存在多个输入约束违规的情况下,只有遇到的第一个会产生错误。在每个违规行为被单独纠正之前,不会发现任何违规行为。

    第二个选项意味着&#34;复制&#34;码。然而,它也倾向于产生更好的用户体验,而来回更少&#34;在应用程序层和业务层之间。 (想象一下网站上有5个错误的表单,并且必须提交并更正表单5次,因为它一次只能告诉您一个错误。)

    哪个更好?这取决于您在应用程序中执行的操作以及所需的整体体验。没有普遍的规则。

    但是代码重复怎么能成为好事呢?嗯,它不是。本质上不是。在许多情况下,这不是问题。实际上,您可能会发现在许多情况下,两个单独层中的验证逻辑实际上并不完全相同。它们针对不同的目的进行验证,并且取决于应用程序在业务逻辑上的传递层与转换层的多少,它们甚至可以验证不同的形状&#34;数据。

    但是,如果它们导致基本相同的验证逻辑。然后你可以从中提取第三个责任&#34;可以移动到自己的类。如果你愿意的话BusinessLogicInputValidator。这可以存在于业务逻辑层内,甚至可以在简单的情况下在BusinessLogic对象内部。它会暴露BusinessLogicApplicationHost使用的相同操作。

    在这种情况下,执行验证的代码将被集中,并且使用验证逻辑的代码将被复制。这没关系,因为消耗逻辑的代码本身并不是逻辑元素,并且实际上不受相同的代码重复和#34;恐惧。