How can I write a method to easily create different types of subclasses

Viewed 70

For a project I have to create objects that represent different types of users. All types are subclasses inheriting from superclass User. In the example we have a Student, Teacher and a Coordinator. Every class has different implementations of certain methods. To know what kind of user we are dealing with, a record is pulled from a database, including a user role. Depending on the role, a different type of User subclass is created. Currently I am using a switch statement a seen below. However, since they all have identical constructors, this results in very repetitive code. How could this be done more elegant/efficiently?

public void makeUserTypes() {
        switch (idRole) {
            case 0:
                user = new Student(idUser, username, firstName, lastName);
                break;
            case 1:
                user = new Teacher(idUser, username, firstName, lastName);
                break;
            case 2:
                user = new Coordinator(idUser, username, firstName, lastName);
                break;
        }
    }
1 Answers

How about a functional interface, with a switch or map?

public interface UserCtor<U> {
  U create(String idUser, String username, String firstName, String lastName);
}

And then you can do this:

public void makeUserTypes() {
    UserCtor<?> ctor = null;
    switch (idRole) {
        case 0:
            ctor = Student::new;
            break;
        case 1:
            ctor = Teacher::new;
            break;
        case 2:
            ctor = Coordinator::new;
            break;
    }
    user = ctor.create(idUser, username, firstName, lastName);
}

Or you can use a map:

private static Map<Integer, UserCtor<?>> ctorMap = Map.of(
    0, Student::new,
    1, Teacher::new,
    2, Coordinator::new
);

public void makeUserTypes() {
    user = ctorMap.get(idRole).create(idUser, username, firstName, lastName);
}

Or an array (which I wouldn't recommend because it assumes that idRole starts at 0 and doesn't skip numbers)

private static UserCtor<?>[] ctors = {Student::new, Teacher::new, Coordinator::new};

public void makeUserTypes() {
    user = ctors[idRole].create(idUser, username, firstName, lastName);
}
Related