I looked multiple places for some advice on how to solve this before asking this question, but I couldn't find something similar to this.
So I have the following scenario in Java Spring Integration
Let's say I have some super class type
class Foo {
private String error;
public Foo(error) {
this.error = error;
}
public boolean isError(){
return !(error.equals("SUCCESS"));
}
}
and then a few subclasses
class Bar extends Foo {
private String name;
public Bar(String name) {
this.name = name
super("SUCCESS");
}
public String getName(){
return name;
}
// more methods
}
And there are more classes that are subclasses of Foo
each with different methods. Now I have a Spring integration Gateway Facade that returns the supertype Foo, with a route that contacts different endpoints and returns a different subclass of Foo based on the request, or in some cases an error which is actually an instantiation of Foo containing the error string. The error comes from the Facades error handler.
public interface Facade {
Foo facadeMethod(Map<String, String> requestMap);
}
public class ErrorHandler {
// arguments not important hence "..."
public Foo handle(...) {
return new Foo("ERROR");
}
}
The way I am currently handling this is:
Foo response = facade.facadeMethod(requestMap);
if (response.isError()) {
// do something
}
Bar bar = (Bar)response;
String name = bar.name();
// something with bar methods
It is guaranteed that if isError
is false, the type I downcast to is actually of the subclass type. The route is selected based on a key/value pair in the requestMap
.
I could throw an exception instead of having an error code, but I still have the same issue of needing to downcast since the facade needs to return a more general type (super class). I don't see how to use generics to solve this, since the Facade method is not in the inheritance hierarchy of Foo/Bar and the other sub classes. I also thought about using a factory but I didn't see how to use that either.
This all feels messy, and I would like to avoid downcasting. Is there any way that is cleaner and better Java practice, or am I stuck with downcasting? Maybe I am missing something obvious here.