我应该验证构造函数中的参数吗?
Posted
技术标签:
【中文标题】我应该验证构造函数中的参数吗?【英文标题】:Should i validate parameters in constructor? 【发布时间】:2013-02-17 15:13:58 【问题描述】:我正在按照 MVC 模式创建一个 Web 应用程序。
在有效的Java中,作者提到在创建新对象时验证类的构造函数中的参数。
但是,我并没有创建一些将被第三方使用的 API。我的类只接受来自表单输入字段的参数,这些参数在提交到服务器之前经过验证。
那么在这种情况下,我应该按照作者在 Effective java 中提到的方式创建我的类还是没用?
【问题讨论】:
请问作者提到的验证构造函数中的参数的书你是从哪里读到的? 【参考方案1】:它不像阅读一本书并执行它所说的那样清晰。您需要思考并将知识应用到您的具体情况。
这实际上取决于您如何初始化类中的变量以及在对象构造后立即使用它们:
一些提示:
如果变量将被类中的某些方法使用,或者对象将在构造后立即被重用(在大多数情况下会),您应该验证所需的值不为空或 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;
后者使我能够干净地退出调用者的有效异常,这不会影响对象的创建(我不喜欢在构造函数中抛出异常)。
简而言之,您的变量是否有约束?如果是,请在将它们设置为内部数据属性之前验证这些约束。
【讨论】:
当传入的参数无效时,您甚至不应该完成对象的构造。你应该抛出一个IllegalArgumentException,而不是创建一个类不变量被破坏的对象。如果您的调用者给您提供了错误的参数,那么它们应该是具有正确上下文来处理它们的参数,这可能包括从用户那里收集新输入并在此之后重新尝试实例化。【参考方案2】:我建议验证您域中的数据并在未正确填写字段时返回(自定义)异常。这样您就可以实现不同的 UI,而无需再次执行整个验证过程,最好尽可能将其分开。
【讨论】:
【参考方案3】:乍一看,没有必要验证参数,因为之前已经完成了验证。但是你应该考虑到你的类会在其他情况下使用,你不能确定每次你的构造函数的输入都是有效的。
【讨论】:
【参考方案4】:听起来您正在验证之前已经验证过的字段。 在这种情况下,这只是浪费时间(无论是编写它还是在运行时)。如果您的表单(客户端 javascript)没有验证这些字段,那么这将是有意义的。否则你可以跳过它。
【讨论】:
信任客户端验证是你能做的最糟糕的事情之一。 是的,这是真的。这就是为什么我也在服务器上验证它们。 如果你要扣分,你应该解释原因,而不仅仅是“这很糟糕”。在作者订阅的场景中,它听起来不像验证是“复杂的”(即,这封电子邮件是否已经存在于数据库中?)。听起来也不是 Web 以外的任何 API 都在访问服务器。那么,为什么只验证客户端会“不好”呢? @ShinySpiderdude 也许这有帮助:***.com/questions/3483514/…以上是关于我应该验证构造函数中的参数吗?的主要内容,如果未能解决你的问题,请参考以下文章