Skip to main content
4 of 7
added 17 characters in body
user avatar
user avatar

Creating a Student class for a project

To recover from yesterdays disaster, I re-read the SOLID principles and refactored my code. Hopfully I did a better job than yesterday. I wanted to keep my Student class immutable, but that meant I would have to change the class everytime a new Student type was introduced, that violated the S in SOLID. Here is what I came up with.

public interface StudentStatus {
    Collection<String> retrieveDocuments();
    StudentType retrieveStatus();
}

public final class Student {

   private final String ID;
   private final String firstname;
   private final String lastname;
   private final StudentStatus status;

   public Student(String iD, String firstname, String lastname, StudentStatus status) {
       ID = iD;
       this.firstname = firstname;
       this.lastname = lastname;
       this.status = status;
   }

   public Collection<String> retrieveDocuments() {
       return status.retrieveDocuments();
   }

   public StudentType retrieveStatus() {
      return status.retrieveStatus();
   }

My requirements are:

  • Domestic students don't require documentation
  • International student do require documentation (passports, etc..)

Domestic Implementation:

    public final class Domestic implements StudentStatus {

       private final StudentType type;
       private final Collection<String> documents;

       public Domestic() {
           this.type = StudentType.Domestic;
           this.documents = Collections.emptyList();
       }
    
       @Override
       public Collection<String> retrieveDocuments() {
           return this.documents;
       }

       @Override
       public StudentType retrieveStatus() {
           return type;
       }
   }

International Implementation:

    public final class International implements StudentStatus {
            
       private final StudentType type;
       private Collection<String> documents;
    
       public International(Collection<String> documents) {
        
           this.type = StudentType.International;
           this.documents = Collections.unmodifiableCollection(documents);
       }

       @Override
       public Collection<String> retrieveDocuments() {
           return Collections.unmodifiableCollection(documents);
       }

       @Override
       public StudentType retrieveStatus() {
          return type;
       }
    }

If there is any new type of status, it can be added my implementing StudentStatus, no need to modify the Student class.

Use:

        List<String> documents = new ArrayList<String>();
        documents.add("Passport");
        documents.add("Drivers License");
        
        StudentStatus domestic = new Domestic();
        StudentStatus international = new International(documents);
        
        List<Student> students = new ArrayList<Student>();
        students.add(new Student("123456789","Susan","Ceesharp", domestic));
        students.add(new Student("987654321","Bill","Finalclass", international));
        
        for(Student display : students) {
            System.out.println(display.getID() + " " + display.retrieveStatus());
        }

I'm aware none of my classes have validation, I kept these out to keep my code clear and concise.

Goal: Keep the Student immutable without violating SOLID.

user150904