Skip to main content
added 63 characters in body
Source Link

if the constructor were made public I would then have to validate the student, using a private method, to ensure that if the student is domestic, the client can't pass a list of documents by throwing an exception. The static methods allowed the creation of the student objects and the client can't pass a List documents for domestic students, and there is no need to throw an exception.

This assumption is simply wrong because your factory method does not check any argument. So there is no difference whether you create your Student objects vis your factory method or not.

On the other hand having a factory method that really checks consistency of the parameters is a good practice. But there is no need to have that in the class itself and therefor it does not need to be static. Especially if you do not take all the parameters in one method but provide a separate setter for each. The name for is Builder Pattern.

StudenBuilder{
    private  String id;
    private  String firstname;
    private  String lastname;
    private  Collection<String> documents;
    private  StudentType typeofStudent;

   public StudenBuilder withId(String id){ 
     this.id=id;
     return this;
   }
   public StudenBuilder withFirstname(String firstname){ 
     this.firstname=firstname;
     return this;
   }
   public StudenBuilder withLastname(String lastname){ 
     this.lastname=lastname;
     return this;
   }
   public StudenBuilder with(Collection<String> documents ){
     Collections.unmodifiableList(new ArrayList<String>(documents));
      return this;
   }
   public StudenBuilder withStudentType(StudentType typeofStudent ){
      this.typeofStudent=typeofStudent;
     return this;
   }
   public Student build(){
      // check consistency
      // e.g. require documents for a certain StudentType
      return new Student(id, firstname, lastname, documents, typeofStudent);
   }
}

The usage would look like this:

Student newStudent = new StudentBuilder()
                     .withId("someId")
                     .withFirstName("some first name")
                     .withLastName("some last name")
                     .withStudentType(StudentType.SOME)
                     .build();

if the constructor were made public I would then have to validate the student, using a private method, to ensure that if the student is domestic, the client can't pass a list of documents by throwing an exception. The static methods allowed the creation of the student objects and the client can't pass a List documents for domestic students, and there is no need to throw an exception.

This assumption is simply wrong because your factory method does not check any argument. So there is no difference whether you create your Student objects vis your factory method or not.

On the other hand having a factory method that really checks consistency of the parameters is a good practice. But there is no need to have that in the class itself and therefor it does not need to be static. Especially if you do not take all the parameters in one method but provide a separate setter for each. The name for is Builder Pattern.

StudenBuilder{
    private  String id;
    private  String firstname;
    private  String lastname;
    private  Collection<String> documents;
    private  StudentType typeofStudent;

   public StudenBuilder withId(String id){ 
     this.id=id;
     return this;
   }
   public StudenBuilder withFirstname(String firstname){ 
     this.firstname=firstname;
     return this;
   }
   public StudenBuilder withLastname(String lastname){ 
     this.lastname=lastname;
     return this;
   }
   public StudenBuilder with(Collection<String> documents ){
     Collections.unmodifiableList(new ArrayList<String>(documents));
      return this;
   }
   public StudenBuilder withStudentType(StudentType typeofStudent ){
      this.typeofStudent=typeofStudent;
     return this;
   }
   public Student build(){
      // check consistency
      return new Student(id, firstname, lastname, documents, typeofStudent);
   }
}

The usage would look like this:

Student newStudent = new StudentBuilder()
                     .withId("someId")
                     .withFirstName("some first name")
                     .withLastName("some last name")
                     .withStudentType(StudentType.SOME)
                     .build();

if the constructor were made public I would then have to validate the student, using a private method, to ensure that if the student is domestic, the client can't pass a list of documents by throwing an exception. The static methods allowed the creation of the student objects and the client can't pass a List documents for domestic students, and there is no need to throw an exception.

This assumption is simply wrong because your factory method does not check any argument. So there is no difference whether you create your Student objects vis your factory method or not.

On the other hand having a factory method that really checks consistency of the parameters is a good practice. But there is no need to have that in the class itself and therefor it does not need to be static. Especially if you do not take all the parameters in one method but provide a separate setter for each. The name for is Builder Pattern.

StudenBuilder{
    private  String id;
    private  String firstname;
    private  String lastname;
    private  Collection<String> documents;
    private  StudentType typeofStudent;

   public StudenBuilder withId(String id){ 
     this.id=id;
     return this;
   }
   public StudenBuilder withFirstname(String firstname){ 
     this.firstname=firstname;
     return this;
   }
   public StudenBuilder withLastname(String lastname){ 
     this.lastname=lastname;
     return this;
   }
   public StudenBuilder with(Collection<String> documents ){
     Collections.unmodifiableList(new ArrayList<String>(documents));
      return this;
   }
   public StudenBuilder withStudentType(StudentType typeofStudent ){
      this.typeofStudent=typeofStudent;
     return this;
   }
   public Student build(){
      // check consistency
      // e.g. require documents for a certain StudentType
      return new Student(id, firstname, lastname, documents, typeofStudent);
   }
}

The usage would look like this:

Student newStudent = new StudentBuilder()
                     .withId("someId")
                     .withFirstName("some first name")
                     .withLastName("some last name")
                     .withStudentType(StudentType.SOME)
                     .build();
Source Link

if the constructor were made public I would then have to validate the student, using a private method, to ensure that if the student is domestic, the client can't pass a list of documents by throwing an exception. The static methods allowed the creation of the student objects and the client can't pass a List documents for domestic students, and there is no need to throw an exception.

This assumption is simply wrong because your factory method does not check any argument. So there is no difference whether you create your Student objects vis your factory method or not.

On the other hand having a factory method that really checks consistency of the parameters is a good practice. But there is no need to have that in the class itself and therefor it does not need to be static. Especially if you do not take all the parameters in one method but provide a separate setter for each. The name for is Builder Pattern.

StudenBuilder{
    private  String id;
    private  String firstname;
    private  String lastname;
    private  Collection<String> documents;
    private  StudentType typeofStudent;

   public StudenBuilder withId(String id){ 
     this.id=id;
     return this;
   }
   public StudenBuilder withFirstname(String firstname){ 
     this.firstname=firstname;
     return this;
   }
   public StudenBuilder withLastname(String lastname){ 
     this.lastname=lastname;
     return this;
   }
   public StudenBuilder with(Collection<String> documents ){
     Collections.unmodifiableList(new ArrayList<String>(documents));
      return this;
   }
   public StudenBuilder withStudentType(StudentType typeofStudent ){
      this.typeofStudent=typeofStudent;
     return this;
   }
   public Student build(){
      // check consistency
      return new Student(id, firstname, lastname, documents, typeofStudent);
   }
}

The usage would look like this:

Student newStudent = new StudentBuilder()
                     .withId("someId")
                     .withFirstName("some first name")
                     .withLastName("some last name")
                     .withStudentType(StudentType.SOME)
                     .build();