> 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<String> 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();