验证方法的参数

时间:2010-07-28 16:08:45

标签: java validation methods argument-passing

关于在对象中包含参数时验证方法参数的最佳实践,我有一个问题。例如,如果您有:

public class Student {
   public int getStudentId();

   public String getStudentName();

   public String getStudentSSN();

   public double getStudentGpa();

   public String getStudentMajor();

   // Other student related getters
}

然后,我有一个方法:

public void printStudentReport(Student student);

在这种方法中,我需要执行涉及ID,名称,GPA和主要的逻辑。所以,那些是必需的。所有其他学生的getter不必填充。可以先验证Student对象,然后再用我需要的四种方法吗?我觉得这有点误导,因为我将此Student对象传递给此方法,但并非所有字段都是必需的,因此它实际上是一个半填充对象被发送到此方法。我觉得很奇怪。

7 个答案:

答案 0 :(得分:2)

如果必须必须填充某些属性才能使Student有效,则应考虑使用所需参数定义非默认构造函数,并从类中删除任何默认构造函数(如果需要) ,验证getter中的属性值)。这可确保只能创建有效的Student对象。

如果其他属性对于学生来说真的是可选的,那对我来说看起来完全没问题。当然,您需要仔细考虑用例并仔细分析域模型,以确定哪些参数是必需的,哪些是可选的。

答案 1 :(得分:1)

考虑一下您正在创建的概念:学生报告。该方法仅使用一组学生数据并不重要,因为这些是您报告的当前要求。也许他们将来会改变。也许他们不会。但它似乎是正确的设计,因为它更易于改变。

现在验证比较棘手。报告是否需要特殊的验证,与学生的正常验证不同?如果是这种情况,那么请务必在报告中对其进行验证:

public void printStudentReport(Student student) {
  validateStudent(student);
  // print the report....
}

但是如果验证对于一组客户端(可能是printStudentReportsaveStudentInDatabase)是常见的,那么您可以创建验证类:

public class FloogleStudentValidator { // or some good name that tells us what this validation does
  public void validate(Student student) { }
}

// ...

public void printStudentReport(Student student) {
  new FloogleStudentValidator().validate(student);
  // print the report....
}

您可以为不同类型的学生验证设置不同的课程。

但是,如果验证对于整个系统来说是常见的,那么我宁愿把它放在Student类本身中,要么在它填充在学生实例中时验证它。

public void printStudentReport(Student student) {
  student.validate();
  // print the report....
}

答案 2 :(得分:0)

如果你只需要4个来自学生的属性,那么我强烈建议你改变你的方法来单独学习它们。

通过这种方式,您可以将您的打印方法与学生分开,并带来所有带来的好处。

答案 3 :(得分:0)

一个选项是让Student对象验证它的数据创建(以及编辑期间),因此当您传递Student对象时,您始终可以确定它们是有效的。

但是有一个假设是,在程序的所有区域中,相同的验证约束将适用于Student对象,因此可能不是一个选项。

答案 4 :(得分:0)

人口稀少的物体很常见。特别是如果您无法控制填充对象的数据源。我说只需要验证printStudentReport()所需的Student字段就可以了。我经常编写类似的报告生成方法,这些方法根据必要的数据进行验证,但如果存在,则会提供来自对象的任何额外数据。

答案 5 :(得分:0)

你也可以尝试接口方法,而不是传递学生对象,你传递一个接口。这意味着您可以拥有仅实现该对象的该部分的学生对象。

public void printStudentReport(MyInterface student)

接口可以包含验证方法

答案 6 :(得分:0)

我遇到的一个问题是逻辑是否真的是报告逻辑或学生逻辑。在报告中,您可以编码:

  thing = (student.getX() + student.getY() ) * student.getZ();

或只是

  thing = student.getThing();

我认为可能有些东西属于学生。

那么我们得到的情况是,我们无法计算事物,因为某些X,Y或Z未正确初始化。因此调用getThing()可能会抛出异常,但这感觉很奇怪。为什么一个对象提供了一些getThing()功能但是却无法做到呢?

在我看来,您的学生课程需要重构。学生可以执行一系列核心功能,并且足以允许生成某些报告。因此,您可以说IRegistered接口和更丰富的IActiveStudent接口。您的报告类需要IRegistered,其他类需要IActiveStudent。

各种学生对象在其一生中改变了他们的能力,就像Caterpiller变成了飞蛾。你没有在caterpiller上使用fly()方法,因此你不需要在所有lepidoptra类上使用canYouFlyYet()方法。