I'm facing a problem with my current design for an Event/Action mechanism. There are numerous Events, that can be distinguished by certain criteria. This results in a class hierarchy.
public interface Event
, public abstract class EventCategory implements Event
and an actual event e.g. public class ActualEvent extends EventCategory
. Then there are Actions which are able to perform operations based on the Event given.
public interface Action<T extends Event> {
void execute(T event);
}
and an actual Action ActualAction<T extends EventCategory> implements Action<T>
.
Now there are Factories that generate the specific instances,
public interface ActionFactory<T extends Event> {
Action<T> create(String actionData);
}
public class ActualActionFactory implements ActionFactory<EventCategory> {
@Override
Action<T> create(String actionData);
}
Finally there are EventConsumers, each has one action and will handle the occurence of events and will execute the constructed action.
public interface EventConsumer<T extends Event> {
void handleEvent(T event);
}
public interface EventConsumerFactory<T extends Event> {
EventConsumer<T> create(String data, Action<T> action);
}
The orchestrator class, which holds all ActionFactories and delegates the create Calls
public class Orchestrator {
private final List<ActionFactory<? extends Event>> factories = Lists.newArrayList();
private final List<EventConsumerFactories<? extends Event>> consumerFactories = Lists.newArrayList();
public void createAction(String actionData) {
for (ActionFactory<? extends Event> factory : factories) {
Action<? extends Event> action = factory.create(actionData);
if (action != null) {
consumerFactories.forEach(cf -> cf.create(null, action));
}
}
Im struggling with the last part. If type the Action as above, Action<? extends Event>
the create call for consumerFactories complains "Required <capture of ? extends Event>, provided <capture of ? extends Event>".
What is the problem with my class hierarchy or template bounds? If use raw types for the action at this place everything works and the actions execute for the configured events. But i would like to get rid of the raw types.
Thanks for your help!
Kind Regards, Andreas
Edit: adding code how factories are registered
public interface EventConsumerFactory<T extends Event> {
EventConsumer<T> create(String consumerData, Action<? super Event> action);
}
public class ActualEventConsumerFactory implements EventConsumerFactory<ActualEvent> {
}
Orchestrator Registration
void registerConsumerFactory(ConsumerFactory<? super Event> factory) {
this.consumerFactories.add(factory);
}