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

问题描述:

我正在创建一个遵循MVC模式的Web应用程序。我应该验证构造函数中的参数吗?

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

但是我没有创建一些第三方使用的API。我的类只接受来自表单的输入字段的参数,这些参数在被定位到服务器之前被验证。

所以在这种情况下,我应该创建我的类的方式作者提到有效的Java或它是无用的?

+0

你在书中读过哪些内容,作者提到要在构造函数中验证参数? – Kwadz 2017-03-01 12:13:23

它不像阅读一本书并实施它所说的那样清晰。您需要思考并将知识应用于您的具体情况。

这真的取决于你如何初始化在类的变量和使用这些对象构造之后:

一些指针:

  • 如果变量要通过一些方法来使用在类中或对象将在构造之后重新使用(在大多数情况下将会),您应该验证所需的值不为空或为空,以避免产生讨厌的异常。

  • 第二次验证输入参数是当您希望将正确的值设置为特定的内部变量时。如果您需要将参数限制在特定的值范围内,那么验证是非常重要的。

例子:

说我们有在该对象的工资帽:

int salary = 0; 
int salaryCap = 1000; 

在创建过程中,你可以验证在工资总额中传递:

public Employee(int salary) { 
if(salary >= this.salaryCap) 
    this.salary = salary; 
} 
  • 班级关系也决定您是否要验证th e值还是不值。例如,如果将参数传递给继承链,我会花时间验证它们,特别是如果它们会影响继承链中其他对象的状态。

例子:

每当我不得不调用超构造函数,我忍不住要验证输入:

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; 
} 
} 

后者给了我的能力,以干净地从有效的异常给调用者,这将不会影响对象的创建退出(我不喜欢在构造函数中抛出异常)。

简而言之,你的变量是否有约束?如果是,请在将这些约束设置为内部数据属性之前验证这些约束。

+10

当传入的参数无效时,你甚至不应该完成构造对象。您应该抛出[IllegalArgumentException](http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/IllegalArgumentException.html),并且不要创建具有破坏的类不变量的对象。如果你的调用者给你提供了不好的参数,那么他们应该是那些具有正确上下文的人来处理它们,这可能包括从用户那里收集新的输入并在那之后重新尝试实例化。 – Jazzepi 2013-03-03 13:49:37

听起来好像你正在验证已经被验证的字段。 在这种情况下,这只是浪费时间(无论是在写入时还是在运行时)。如果你的表单(客户端JavaScript)没有验证字段,那么它是有道理的。否则,你可以跳过它。

+4

Trusting * clientside *验证是您可以做的最糟糕的事情之一。 – PeeHaa 2013-03-03 13:39:57

+0

是的,这是真的。这就是为什么我在服务器上验证它们的原因。 – 2013-03-03 13:44:41

+0

如果你扣分,你应该解释为什么,而不仅仅是“非常糟糕”。在作者订阅的情况下,听起来不像验证是“复杂的”(即,这个电子邮件是否已经存在于数据库中?)。它听起来不像是网络访问服务器以外的任何API。那么,为什么只验证客户端会是“坏”呢? – ShinySpiderdude 2013-03-03 14:30:06

一见钟情,没有必要验证参数,因为验证是在之前完成的。但是你应该考虑到在其他情况下你的类将被使用,你不能确定每次你的构造函数的输入是有效的。

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