I have an interface:
public interface Handler<E extends Event> {
void handle(E event);
}
And two implementations of it:
public class SignupEventHandler implements Handler<SignupEvent> {
@Override
public void handle(SignupEvent event) {}
}
and
public class SignoutEventHandler implements Handler<SignoutEvent> {
@Override
public void handle(SignoutEvent event) {}
}
Note that Event in itself is an interface, that is implemented by both SignupEvent and SignoutEvent.
I am wondering what's the correct way to implement a factory for Handler.
public class HandlerFactory {
public static Handler<? extends Event> getHandler(Event event) {
if(event.type().equals("SignupEvent")) {
return new SignupEventHandler();
} else if(event.type().equals("SignoutEvent")) {
return new SignoutEventHandler();
} else {
throw new IllegalArguementException("Unrecognised event type");
}
}
}
The problem I am facing is that I can't do HandlerFactory.getHandler(event).handle(event) as it wants a capture of ? of Event.
Event event = getDeserialisedEvent(message, Event.class);
Handler<? extends Event> handler = HandlerFactory.getHandler(event);
handler.handle(event); //can't do this
Is there a clean way to accomplish this? One way I found was:
public class HandlerFactory {
public static <E extends Event> Handler<E> getHandler(E event) {
if(event.type().equals("SignupEvent")) {
return (Handler<E>) new SignupEventHandler(); //unchecked cast, but it's guaranteed to be type-safe
} else if(event.type().equals("SignoutEvent")) {
return (Handler<E>) new SignoutEventHandler(); //unchecked cast, but it's guaranteed to be type-safe
} else {
throw new IllegalArguementException("Unrecognised event type");
}
}
}
This approach works, but I wonder if there is a cleaner way to do this.