I'm creating an application containing a class I'm writing called Person. One of the fields of Person is 'aliases' which is an ArrayList<String>. Ultimately the aliases will be displayed to the user according to the following logic: If Person has aliases then they should be displayed as [Finch, Wren, Admin, etc...], otherwise UNKNOWN should be displayed. So far I've tried implementing this in one of three ways:
Person contains the method
getAliases()which simply returns a copy of the ArrayList as is. The caller checks for an empty array to implement the desired behavior.Person contains the method
aliasesToString()which can be called to produce the desired string.Instead of using
ArrayList<String>, aliases is an implementation ofDefaultableArrayList<T>. This class extends ArrayList and holds a default value with type T. ThetoString()method is overriden to produce the desired string. The application callssome_person.getAliases().toString()to produce the desired behavior.
Below is my implementation of option 3:
public class DefaultableArrayList<T> extends ArrayList<T> {
private static final long serialVersionUID = -6735356930885363889L; // Auto-generated
private final T defaultElement;
public DefaultableArrayList(T defaultElement) {
super();
this.defaultElement = defaultElement;
}
public DefaultableArrayList(Collection<? extends T> c, T defaultElement) {
super(c);
this.defaultElement = defaultElement;
}
public DefaultableArrayList(int initialCapacity, T defaultElement) {
super(initialCapacity);
this.defaultElement = defaultElement;
}
public T getDefaultElement() {
return defaultElement;
}
@Override
public String toString() {
if (!isEmpty()) {
return super.toString();
} else {
return defaultElement.toString();
}
}
}
What concerns me about options 2 and 3 is that I might be adding needless complexity whilst violating OOP guidelines. Should Person really be concerned with what happens if there's no aliases and does it make sense for aliases to define how it's ultimately implemented in the application? I think that I should be letting the caller handle the empty case. Which option should I choose that best meets standard OOP design guidelines? Or is there a fourth option that I haven't considered?