I have one class, let’s call it ClassA, and a bunch of subclasses of it, and subsequent subclasses of those classes. ClassA, and every class below it takes a String at an argument in their constructor. I have a bunch of String objects that I need to ‘convert’ into subclasses of ClassA.
The current way I am doing it is with is isType(String) method that checks if the String is an instance of that subclass, but it seems like very bad programming technique to use a huge if-else or switch-case statement to find the correct type of ClassA that the String is. It there a common way to go down a sub-class structure, or is the way that I have been doing it okay?
The purpose of this is that I am making a scripting language (for a fun project) and I need to be able identify what something is. (Data type that is)
Example code:
public static boolean isType(String data) {
data = data.trim();
return edu.ata.script.data.Boolean.isType(data)
|| edu.ata.script.data.Integer.isType(data)
|| edu.ata.script.data.Double.isType(data)
|| DATA_STORAGE.contains(data)
|| ReturningMethod.isType(data)
|| edu.ata.script.data.String.isType(data);
}
public static Data get(String data) {
data = data.trim();
/*:)*/ if (edu.ata.script.data.Boolean.isType(data)) {
return edu.ata.script.data.Boolean.get(data);
} else if (edu.ata.script.data.Integer.isType(data)) {
return edu.ata.script.data.Integer.get(data);
} else if (edu.ata.script.data.Double.isType(data)) {
return edu.ata.script.data.Double.get(data);
} else if (DATA_STORAGE.contains(data)) {
return (Data) DATA_STORAGE.get(data);
} else if (ReturningMethod.isType(data)) {
return ReturningMethods.getMethodValue(data);
} else if (edu.ata.script.data.String.isType(data)) {
// Last option because everything is accepted.
return edu.ata.script.data.String.get(data);
} else {
throw new RuntimeException("Could not parse data - " + data);
}
}
I was indeed understanding something totally different, so I’m re-editing this answer.
I suspect that you’re working in some sort of importation script or something and that the
edu.ata.script.data.*are the ClassB, ClassC, etc that you were writing and they know how to convert stuff from one format to another… (This is just guessing)My suggestion to get rid of all the if then else in the
get(String data)method is that you implement a chain of responsability. That way you can have a chain that registers the several edu.ata.script.data.* in a List and then you iterate through that list until one of them returns true for the isType(string) knowing which subclass you want to use to process the string.To remove the list of ORs in the
isType(String data)method is a bit trickier and probably this is a bit over enginnering, but you can do the following:Look in your classpath for classes that are assignableFrom your class
Then when you would retrieve all the classes that were assignable by your own you would have to invoke via reflection the isType of each one to know the result
I know you might find yourself a bit lost regarding the 1st point, best way is to look into ResolverUtil class from Stripes Framework where they do that in the method
loadImplementationsFromContextClassloader