Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该验证构造函数中的参数吗?_Java_Model View Controller_Design Patterns - Fatal编程技术网

Java 我应该验证构造函数中的参数吗?

Java 我应该验证构造函数中的参数吗?,java,model-view-controller,design-patterns,Java,Model View Controller,Design Patterns,我正在按照MVC模式创建一个web应用程序 在有效的Java中,作者提到在创建新对象时验证类构造函数中的参数 然而,我并没有创建一些将由第三方使用的API。我的类只接受表单输入字段中的参数,这些参数在提交到服务器之前经过验证 因此,在这种情况下,我应该按照作者在有效java中提到的方式创建类,还是这样做没有用?听起来您在验证之前已经验证过的字段。 在这种情况下,这只是浪费时间(包括编写和运行时)。如果您的表单(客户端javascript)没有验证字段,那么它是有意义的。否则你可以跳过它。它不像读

我正在按照MVC模式创建一个web应用程序

在有效的Java中,作者提到在创建新对象时验证类构造函数中的参数

然而,我并没有创建一些将由第三方使用的API。我的类只接受表单输入字段中的参数,这些参数在提交到服务器之前经过验证


因此,在这种情况下,我应该按照作者在有效java中提到的方式创建类,还是这样做没有用?

听起来您在验证之前已经验证过的字段。
在这种情况下,这只是浪费时间(包括编写和运行时)。如果您的表单(客户端javascript)没有验证字段,那么它是有意义的。否则你可以跳过它。

它不像读书和实现它所说的那样清晰。你需要思考并将知识应用到你的具体情况中

这实际上取决于您如何初始化类中的变量,并在对象构造之后立即使用它们:

一些建议:

  • 如果类中的某些方法将使用变量,或者对象将在构造之后立即重新使用(在大多数情况下会这样),则应验证所需的值是否为空或null,以避免出现令人讨厌的异常

  • 第二次验证输入参数时,您希望为特定的内部变量设置正确的值。如果需要将参数约束到特定的值范围,则验证非常重要

例如:

假设对象中有工资上限:

int salary = 0;
int salaryCap = 1000;
在创建期间,您可以验证传入的薪资金额:

public Employee(int salary) {
 if(salary >= this.salaryCap)
  this.salary = salary;
}
  • 类关系还确定是否要验证值。例如,如果参数将向上传递到继承链,我将花时间验证它们,特别是如果它们将影响继承链中其他对象的状态
例如:

每当我必须调用超级构造函数时,我都会尝试验证输入:

public Employee(int salary) {
 super(salary); //validate salary against known constraints
}
  • 变量来自哪里?如果您不信任源(如sql参数等),那么您应该验证它们,并可能在执行进一步的代码之前清理输入。这可以防止安全攻击

  • 我总是厌倦在构造函数中进行验证和参数检查。我更喜欢使用getter和setter来验证输入。这样,如果在对象创建时发生了某些事情,至少我可以保证半工作对象比完全不一致对象的状态更容易确定。当然,这取决于您的上下文,如果您的约束是严格的,您可以停止对象创建并提示客户机(用户、调用对象等)输入有效的输入参数

使用getter/setter给我带来的好处是,对象实际上是通过调用对象提供的外部接口一步一步地构造的,而不是在创建过程中限制验证,当出现异常时,验证会导致对象不可用/不稳定

因此,与此相反:

public Employee(int salary) {
 if(salary >= this.salaryCap)
  this.salary = salary;
}
我喜欢这样:

public class Employee {
 public void setSalary(int salary) {
  if(salary >= this.salaryCap)
      this.salary = salary;
 }
}
后者使我能够干净地退出调用方的有效异常,这不会影响对象创建(我不喜欢在构造函数中抛出异常)


简而言之,您的变量有约束吗?如果是,请先验证这些约束,然后再将其设置为内部数据属性。

乍一看,不必验证这些参数,因为之前已经完成了验证。但是您应该考虑到您的类将在其他情况下使用,您无法确保每次构造函数的输入都有效。

我建议验证域中的数据,并在字段填写不正确时返回(自定义)异常。这样,您就可以实现不同的UI,而无需再次执行整个验证过程,最好尽可能将其分离。

信任客户端验证是您可以做的最糟糕的事情之一。是的,这是事实。这就是我在服务器上验证它们的原因。如果你在扣分,你应该解释原因,而不仅仅是“非常糟糕”。在作者订阅的场景中,验证听起来并不“复杂”(即,此电子邮件是否已经存在于数据库中?)。这听起来也不像是web以外的任何API正在访问服务器。那么,为什么只验证客户端是“不好的”呢?@shinyspiderdue也许这有帮助:当传入的参数无效时,您甚至不应该完成对象的构造。您应该抛出一个类不变量,而不是创建一个具有损坏的类不变量的对象。如果你的调用者给了你错误的参数,那么它们应该是具有正确上下文的参数来处理它们,这可能包括从用户那里收集新的输入,然后重新尝试实例化。请问你在作者提到的书中读到了什么,以验证构造函数中的参数?