I have a class called Foo
public class Foo {
private String optionalProperty;
private String name;
private long uniqueId;
// getters/setters for above properties
}
For some business reason I need to create an Identifier which I can use to 'identify' Foo instances (having some name
/uniqueId
) in some business flow. I want to create some FooIdentifier
class which will be used to identify Foo
instances (this FooIdentifier
has other business use cases as well and this is one of the use cases).
Since this FooIdentifier
will be either based on name
or uniqueId
we need to distinguish between those two scenarios, optionalProperty
is common in both the scenarios.
I'm considering two designs as follows -
Subclassing -
public abstract class FooIdentifier {
private String optionalProperty;
public enum Type {
NAME_BASED, ID_BASED
}
protected FooIdentifier(String optionalProperty) {
this.optionalProperty = optionalProperty;
}
public String getOptionalProperty() {
return optionalProperty;
}
public abstract Type getType();
}
public class NameBasedIdentifier extends FooIdentifier {
private String name;
public NameBasedIdentifier(String optionalProperty, String name) {
super(optionalProperty);
this.name = name;
}
public NameBasedIdentifier(String name) {
this(null, name);
}
public String getName() {
return name;
}
@Override public Type getType() {
return Type.NAME_BASED;
}
}
public class IdBasedIdentifier extends FooIdentifier {
private long uniqueId;
public IdBasedIdentifier(String optionalProperty, long uniqueId) {
super(optionalProperty);
this.uniqueId = uniqueId;
}
public IdBasedIdentifier(long uniqueId) {
this(null, uniqueId);
}
public long getUniqueId() {
return uniqueId;
}
@Override public Type getType() {
return Type.ID_BASED;
}
}
Or plain old class -
public class FooIdentifier {
private String optionalProperty;
private String name;
private long uniqueId;
public enum Type {
NAME_BASED, ID_BASED
}
public FooIdentifier(String optionalProperty, String name) {
this.optionalProperty = optionalProperty;
this.name = name; // will have null check
}
public FooIdentifier(String optionalProperty, long uniqueId) {
this.optionalProperty = optionalProperty;
this.uniqueId = uniqueId; // will have null check
}
public FooIdentifier(String name) {
this(null, name);
}
public FooIdentifier(long uniqueId) {
this(null, uniqueId);
}
public String getOptionalProperty() {
return optionalProperty;
}
public Type getType() {
return name == null ? Type.ID_BASED : Type.NAME_BASED;
}
public String getName() {
return name;
}
public long getUniqueId() {
return uniqueId;
}
}
Which one will be better?