Is This Use of the "instanceof" Operator Considered Bad Design?
The Visitor pattern is typically used in such cases. Although the code is a bit more complicated, but after adding a new RecordType
subclass you have to implement the logic everywhere, as it won't compile otherwise. With instanceof
all over the place it is very easy to miss one or two places.
Example:
public abstract class RecordType {
public abstract <T> T accept(RecordTypeVisitor<T> visitor);
}
public interface RecordTypeVisitor<T> {
T visitOne(RecordType1 recordType);
T visitTwo(RecordType2 recordType);
}
public class RecordType1 extends RecordType {
public <T> T accept(RecordTypeVisitor<T> visitor) {
return visitor.visitOne(this);
}
}
public class RecordType2 extends RecordType {
public <T> T accept(RecordTypeVisitor<T> visitor) {
return visitor.visitTwo(this);
}
}
Usage (note the generic return type):
String result = record.accept(new RecordTypeVisitor<String>() {
String visitOne(RecordType1 recordType) {
//processing of RecordType1
return "Jeden";
}
String visitTwo(RecordType2 recordType) {
//processing of RecordType2
return "Dwa";
}
});
Also I would recommend throwing an exception:
throw new IllegalArgumentException(record);
instead of returning null
when neither type is found.
My suggestion:
public RecordType process(RecordType record){
return record.process();
}
public class RecordType
{
public RecordType process()
{
return null;
}
}
public class RecordType1 extends RecordType
{
@Override
public RecordType process()
{
...
}
}
public class RecordType2 extends RecordType
{
@Override
public RecordType process()
{
...
}
}
If the code you need to execute is coupled to something the model shouldn't know (like UI) then you will need to use a kind of double dispatch or visitor pattern.
http://en.wikipedia.org/wiki/Double_dispatch