代码之家  ›  专栏  ›  技术社区  ›  sma

验证方法的参数

  •  0
  • sma  · 技术社区  · 14 年前

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

    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、name、GPA和major的逻辑。所以,这些是必须的。所有其他的学生获得者不必被填充。可以先验证Student对象,然后验证我需要的四种方法吗?我觉得这有点误导,因为我正在将这个Student对象传递给这个方法,但并不是所有字段都是必需的,所以它实际上是一个半填充的对象被发送给这个方法。我觉得很奇怪。

    7 回复  |  直到 14 年前
        1
  •  2
  •   Péter Török    14 年前

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

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

        2
  •  1
  •   Jordão    14 年前

    想想你正在创造的概念: . 该方法只使用一组学生数据并不重要,因为这些数据是当前的 要求 ,因为它更能适应变化。

    现在验证更加棘手。报告是否需要特殊的验证,不同于学生的正常验证?如果是这样的话,那么请务必在报告中确认:

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

    printStudentReport saveStudentInDatabase ),则可以创建验证类:

    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....
    }
    
        3
  •  0
  •   pauljwilliams    14 年前

    这样你就把你的打印方法和学生脱钩了,带来了很多好处。

        4
  •  0
  •   BruteForce    14 年前

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

        5
  •  0
  •   waltwood    14 年前

    半填充对象很常见。尤其是当您无法控制填充对象的数据源时。我认为只验证printstudenreport()所需的Student字段就可以了。我经常编写类似的报告生成方法,根据必要的数据进行验证,但如果存在对象,则会提供来自该对象的任何额外数据。

        6
  •  0
  •   AndersK    14 年前

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

    public void printStudentReport(MyInterface student)
    

        7
  •  0
  •   djna    14 年前

    我想到的一个问题是,逻辑到底是报告逻辑还是学生逻辑。在报告中,您可以编写:

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

    或者只是

      thing = student.getThing();
    

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

    所以我们得到了我们无法计算的情况 因为有些X、Y或Z没有正确初始化。所以调用getThing()可能会抛出异常,但这感觉很奇怪。为什么一个对象应该提供一些getThing()功能,但却不能做到呢?

    在我看来,你的学生班级需要重构。学生们有一套核心的能力可以做,他们足以让某些报告产生。因此,您必须假设IRegistered接口和更丰富的IActiveStudent接口。你的报告类需要i注册,其他类需要i活动学生。