21

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

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

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

那么在这种情况下,我应该按照作者在 Effective java 中提到的方式创建我的类还是没用?

4

4 回答 4

13

It is not as clear cut as reading a book and implementing what it says. You need to think and apply the knowledge to your specific situation.

It really depends on how you are initializing the variables in your class and using them right after object construction:

Some pointers:

  • If the variables are going to be used by some methods in the class or the object is going to be re-used right after constructions (which in most cases will), you should validate that the values that are required are not empty or null, to avoid getting nasty exceptions.

  • The second time to validate input parameters is when you expect the correct values to be set to specific internal variables. If you require that a parameter be constrained to a specific value range, then it is important that you validate.

Example:

Say we have a salary cap in the object:

int salary = 0;
int salaryCap = 1000;

During creation, you can validate the passed in salary amount:

public Employee(int salary) {
 if(salary >= this.salaryCap)
  this.salary = salary;
}
  • The class relationship also determines whether you want to validate the values or not. If the parameters will be passed up the inheritance chain for-example, I would take the time to validate them, especially if they will affect the state of other objects in the inheritance chain.

Example:

Whenever I have to call the super constructor, I am tempted to validated the input:

public Employee(int salary) {
 super(salary); //validate salary against known constraints
}
  • Where are the variables coming from? If you do not trust the source (like sql parameters etc), then you should validate them and possibly sanitize the input before executing further code. This prevents security attacks.

  • I am always weary to do validation and parameter checking in the constructor. I prefer to have getters and setters to validate input. That way, if something happens at object creation, at least I have the guarantee of semi-working object than a complete inconsistent object whose state cannot be readily determined. Of course this depends on your context, if you constraints are strict, you can stop the object creation and prompt the client (user, calling object etc) for valid input parameters.

The advantage that using getters/setters affords me is that the object is really constructed step by step by calling on the external interface the object gives, other than constraining the validation during creation, which when an exception occurs, renders the object unusable/unstable.

So instead of this:

public Employee(int salary) {
 if(salary >= this.salaryCap)
  this.salary = salary;
}

I prefer this:

public class Employee {
 public void setSalary(int salary) {
  if(salary >= this.salaryCap)
      this.salary = salary;
 }
}

The latter gives me the ability to cleanly exit with a valid exception to the caller, which will not affect object creation (I don't like throwing exceptions in the constructor).

In a nutshell, do your variable have constraints? If yes, validate those constraints before setting them to internal data properties.

于 2013-03-03T13:40:24.333 回答
4

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

于 2013-03-03T13:41:40.210 回答
2

At the first sight it is not necessary to validate the parameters since the validation was done before. But you should take into consideration that your class will be used in other circumstances, you cannot be sure that every time the input of your constructor is valid.

于 2013-03-03T13:40:39.443 回答
-7

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

于 2013-03-03T13:37:37.127 回答